The Best Way To Create Reusable Objects in Javascript - javascript

I have use the prototype and jQuery library. However I want to learn OOP JS more extensively. The kind of things I would like to do is create multiple instances of a JS object to run at the same time. In the example I am working with here, I want to create 7 different boxes to bounce around. I read the best way to create an object multiple times with using prototype. Here is a working script example I have created.
The problem I run into is if uncomment the "this.int = setInterval(this.move,20);", the I get an error that says it can't find "this.box.style.left" in the move function. It seems that the move function gets broken from the bounce object. I have tried everything I can think to make this work. I kind of need to have the int as a variable of the object so I can make a stop function to kill it.
like "bounce.prototype.stop = function() { clearInterval(this.int); });"
HTML
<body onload="dothis()">
<div id="case">
<div class="boxclass" id="box1">BOX</div>
</div>
</body>
CSS
<style type="text/css">
body {
background-color: #3F9;
text-align: center;
margin: 0px;
padding: 0px;
}
#case {
background-color: #FFF;
height: 240px;
width: 480px;
margin-right: auto;
margin-bottom: 72px;
position: relative;
margin-top: 72px;
margin-left: auto;
}
.boxclass {
background-color: #F96;
height: 36px;
width: 36px;
position: absolute;
}
</style>
JAVASCRIPT
<script type="text/javascript">
function bounce(frame,box,speed,x,y) {
this.speed = speed;
this.frame = frame;
this.box = box;
this.fw = frame.offsetWidth;
this.fh = frame.offsetHeight;
this.bx = x;
this.by = y
this.int = '';
return this;
}
bounce.prototype.position = function () {
if (this.box.offsetLeft <= 0 && this.bx < 0) {
console.log('LEFT');
this.bx = -1 * this.bx;
}
if ((this.box.offsetLeft + this.box.offsetWidth) >= this.frame.offsetWidth) {
console.log('RIGHT');
this.bx = -1 * this.bx;
}
if (this.box.offsetTop <= 0 && this.by < 0) {
console.log('TOP');
this.y = -1 * this.y;
}
if ((this.box.offsetTop + this.box.offsetHeight) >= this.frame.offsetHeight) {
console.log('BOTTOM');
this.y = -1 * this.y;
}
return this;
}
bounce.prototype.move = function() {
this.box.style.left = this.box.offsetLeft + this.bx+"px";
this.box.style.top = this.box.offsetTop + this.by+"px";
//this.int = setInterval(this.move,20);
}
function dothis() {
bn1 = new bounce( document.getElementById('case'), document.getElementById('box1'), 10,20,30).position();
bn1.move();
}
</script>

You are missing the context when you call this.move.
Basically, in JS you need to pass the context for calling the method otherwise this.move will run in another context.
You can cache this pointer outside of SetInterval and use that to call it like this:
setInterval(function(context) {
return function() {context.move(); }
} )(this), 20);
OR this:
var that = this;
setInterval(function(){
that.move();
}, 20);

Related

How do I see if one element is touching another in JavaScript without clicking anything

OK so I've tried one thing from a different question and it worked, but not the way I wanted it to. it didn't work the way I wanted it to! You literally had to click when two objects were touching so it would alert you, if somebody can figure out a way to detect if two elements are touching without having to click that would be a life saver! So I hope you people who read this request please respond if you know how. this is the code below. so one object is moving and i want it to make it stop when the object hits the player (i am making a game) the movement is by px.... i want it to keep testing if one object hits the player, and if it does i want it to stop everything.
var boxes = document.querySelectorAll('.box');
boxes.forEach(function (el) {
if (el.addEventListener) {
el.addEventListener('click', clickHandler);
} else {
el.attachEvent('onclick', clickHandler);
}
})
var detectOverlap = (function () {
function getPositions(elem) {
var pos = elem.getBoundingClientRect();
return [[pos.left, pos.right], [pos.top, pos.bottom]];
}
function comparePositions(p1, p2) {
var r1, r2;
if (p1[0] < p2[0]) {
r1 = p1;
r2 = p2;
} else {
r1 = p2;
r2 = p1;
}
return r1[1] > r2[0] || r1[0] === r2[0];
}
return function (a, b) {
var pos1 = getPositions(a),
pos2 = getPositions(b);
return comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);
};
})();
function clickHandler(e) {
var elem = e.target,
elems = document.querySelectorAll('.box'),
elemList = Array.prototype.slice.call(elems),
within = elemList.indexOf(elem),
touching = [];
if (within !== -1) {
elemList.splice(within, 1);
}
for (var i = 0; i < elemList.length; i++) {
if (detectOverlap(elem, elemList[i])) {
touching.push(elemList[i].id);
}
}
if (touching.length) {
console.log(elem.id + ' touches ' + touching.join(' and ') + '.');
alert(elem.id + ' touches ' + touching.join(' and ') + '.');
} else {
console.log(elem.id + ' touches nothing.');
alert(elem.id + ' touches nothing.');
}
}
this is my video game right now (please do not copy)
<!DOCTYPE html>
/
<html>
<form id="player" class="box">
</form>
<button type="button" class="up" onclick="moveup()">^</button>
<button type="button" class="down" onclick="movedown()">v
</button>
<style src="style.css">
#player {
width: 300px;
height: 100px;
background-color: blue;
display: inline-block;
position: relative;
bottom: -250px;
left: 200px;
}
.up {
position: relative;
bottom: -400px;
}
.down {
position: relative;
bottom: -420px;
}
body {
background-color: black;
}
#car {
width: 300px;
height: 100px;
background-color: red;
display: inline-block;
position: relative;
bottom: -250px;
left: 600px;
}
</style>
<form id="car" class="box"></form>
<script>
imgObj = document.getElementById('player');
imgObj.style.position= 'relative';
imgObj.style.bottom = '-250px';
function moveup() {
imgObj.style.position= 'relative';
imgObj.style.bottom = '-250px';
imgObj.style.bottom = parseInt(imgObj.style.bottom) + 70 + 'px';
}
function movedown() {
imgObj.style.position= 'relative';
imgObj.style.bottom = '-250px';
imgObj.style.bottom = parseInt(imgObj.style.bottom) + -120 + 'px';
}
myMove();
function myMove() {
var elem = document.getElementById("car");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 1000) {
clearInterval(id);
myMove();
} else {
pos++;
elem.style.left = pos + "px";
elem.style.left = pos + "px";
}
}
}
/* please do not copy; this is it so far i want the red box when it hits the player(blue box) to stop everything that is happening */
/* made by Jsscripter; car game */
</script>
</html>
Intersection observer. API was largely developed because of news feeds and infinite scrolling. Goal was to solve when something comes into view, load content. Also is a great fit for a game.
The Intersection Observer API lets code register a callback function
that is executed whenever an element they wish to monitor enters or
exits another element (or the viewport), or when the amount by which
the two intersect changes by a requested amount. This way, sites no
longer need to do anything on the main thread to watch for this kind
of element intersection, and the browser is free to optimize the
management of intersections as it sees fit.
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
All major browsers except safari support the API. For backwards compatibility and Safari support can use the polyfill from W3C found here. Check out this example from MDN:
var callback = function(entries, observer) {
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
var options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 1.0
}
var observer = new IntersectionObserver(callback, options);
var target = document.querySelector('#listItem');
observer.observe(target);
See this in action here: https://codepen.io/anon/pen/OqpeMV

DOM assign an id to child Javascript

I have created a grid with div, class and id. I want to randomly create a yellow square and I want to assign an id= 'yellowSquare' how do I do it?
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 100; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var drawPone = document.getElementById('square' + randomIndex);
drawPone.style.backgroundColor = 'yellow';
}
}
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
<div id="grid-box"></div>
I am new to Javascript / jQuery. Any help will be much appreciated ! Thank you
There are two options to your question. You can either change the id of the yellow square which is already created from your code, or create a child element within the square, which looks the same as your current solution. Creating a new child element will let you keep the numeric id pattern for the grid:
Changing the ID :
var element = document.getElementById('square' + randomIndex)
element.id = "yellowSquare";
Adding new element inside:
var node = document.createElement("DIV");
node.id = "yellowSquare";
node.style = "background-color:yellow;height:100%;width:100%;";
var element = document.getElementById('square' + randomIndex)
element.appendChild(node);
I set the styling of the div child to 100% width and height, as it has no content, and would get 0 values if nothing was specified. This should make it fill the parent container.
There are also multiple other ways to achieve the same result, for instance with JQuery.
Use the HTMLElement method setAttribute (source);
...
var drawPone = document.getElementById('square' + randomIndex);
drawPone.style.backgroundColor = 'yellow';
drawPone.setAttribute('id', 'yellowSquare');
...
As you requested in your comment how to move the square i made an example how you can move it left and right using jQuery next() and prev() functions. However because your html elements are 1 dimensional it's not easy to move them up/down and check the sides for collisions. Better would be to create your html table like with rows and columns and this way create a 2 dimensional play field.
Also added a yellowSquery class for selection with $drawPone.addClass('yellowSquare');.
Also since you like to use jQuery I changed your existing code to jQuery function. Might help you learn the framework.
var $grid = $("#grid-box");
for (var i = 1; i <= 100; i++) {
var $square = $("<div>");
$square.addClass('square');
$square.attr('id','square' + i);
$grid.append($square);
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(99 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var $drawPone = $('#square' + randomIndex);
$drawPone.addClass('yellowSquare');
}
}
$('#button_right').on('click', function(){
$yellowSquare = $('.yellowSquare')
$yellowSquareNext = $yellowSquare.next();
$yellowSquare.removeClass('yellowSquare');
$yellowSquareNext.addClass('yellowSquare');
});
$('#button_left').on('click', function(){
$yellowSquare = $('.yellowSquare')
$yellowSquarePrev = $yellowSquare.prev();
$yellowSquare.removeClass('yellowSquare');
$yellowSquarePrev.addClass('yellowSquare');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.yellowSquare {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="grid-box"></div>
<button id="button_left">left</button>
<button id="button_right">right</button><br>

Drawing lines using RequestAnimationFrame()

I want to draw a horizontal line when the game launches and was able to come up with something that drew the line using requestAnimationFrame() and ctx.stroke().
The problem is that when I attempt to edit the length of the line by changing the values of the end point on the line, the line remains the same length.
If anyone could take a look at it and explain what is going on I would really appreciate it.
var canvasTop = document.getElementById('top');
var ctxTop = canvasTop.getContext('2d');
var frameCountTop = 0;
var fpsTop, fpsIntervalTop, startTimeTop, nowTop, thenTop, elapsedTop;
function startAnimatingTop(fpsTop) {
fpsIntervalTop = 1000 / fpsTop;
thenTop = Date.now();
startTimeTop = thenTop;
drawTop();
}
var topLinePointA = [32, 80];
var topLinePointB = [280, 80];
var topLineStart = topLinePointA[0];
var topLineIncrement = topLineStart + 1;
var topLineEnd = topLinePointB[0];
function drawTop() {
var i = 32;
while (i < topLineEnd) {
requestAnimationFrame(drawTop);
i++;
nowTop = Date.now();
elapsedTop = nowTop - thenTop;
if (elapsedTop > fpsIntervalTop && i < topLineEnd) {
thenTop = nowTop - (elapsedTop % fpsIntervalTop);
ctxTop.lineWidth = 20;
ctxTop.strokeStyle = "black";
ctxTop.moveTo(topLineStart, 80);
ctxTop.lineTo(topLineIncrement, 80);
ctxTop.stroke();
topLineStart += 1;
} else {
cancelAnimationFrame(drawTop);
return;
}
}
}
startAnimatingTop(100);
/*HANGMAN STYLES*/
/*CLASS SELECTORS*/
.lineContainer {
/*border-style: solid;
border-color: blue;*/
}
#top {
position: absolute;
height: 5%;
width: 45%;
left: 30%;
}
#side {
position: absolute;
bottom: 20%;
left: 70%;
height: 78%;
width: 5%;
}
#bottom {
position: absolute;
bottom: 35%;
height: 5%;
width: 56%;
left: 20%;
}
#hangman {
position: absolute;
left: 30%;
height: 40%;
width: 10%;
}
<canvas id='top' class='lineContainer'></canvas>
<canvas id='side' class='lineContainer'></canvas>
<canvas id='bottom' class='lineContainer'></canvas>
<canvas id='hangman' class='lineContainer'></canvas>
<canvas id='puzzle'></canvas>
<div id='scorecard'>
</div>
There are many problems with your code.
You need to read up on using the canvas. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D will help.
Only call requestAnimationFrame once per frame. Putting it inside a while loop will just start 1000's of frames fighting for display refresh.
Start paths with ctx.beginPath();
Clear the canvas using ctx.clearRect(0,0,width,height)
Set canvas size via attributes not via style properties.
The first argument to the function called by requestAnimationFrame is the time. eg drawTop(time)
See comments for more info.
ctx.canvas.width = 100; // << set the canvas size via canvas attributes not style
ctx.canvas.height = 100;
var thenTop = performance.now(); // to get time.
requestAnimationFrame(drawTop); // <<< start the render loop with request, dont call direct
function drawTop(nowTop) { // << time passed to render call
requestAnimationFrame(drawTop); // <<< put call here not in loop
ctxTop.clearRect(0, 0, ctxTop.canvas.width, ctxTop.canvas.height); // <<< clear the canvas
var i = 32;
while (i < topLineEnd) {
// requestAnimationFrame(drawTop); // <<<<<<< Not here
i++;
elapsedTop = nowTop - thenTop;
if (elapsedTop > fpsIntervalTop && i < topLineEnd) {
thenTop = nowTop - (elapsedTop % fpsIntervalTop);
ctxTop.lineWidth = 20;
ctxTop.strokeStyle = "black";
ctxTop.beginPath(); // <<<<<< To start a new path
ctxTop.moveTo(topLineStart, 80);
ctxTop.lineTo(topLineIncrement, 80);
ctxTop.stroke();
topLineStart += 1;
} else {
return;
}
}
}

Create custom square grid using jquery

I am working on a project trying to make something resembling an etch-a-sketch. I have a 780x780px square, and I am trying to get a 16x16 grid, using a series of smaller square divs.
It is on this grid that I have the hover effect. I keep getting a 15x17 grid of square divs because the last square of the row won't fit. I have margins set to 1px and padding set to 0 so I figured that to fit 16 squares on a 780px wide row, it would require me to take into account the margins (15 1px margins) and from there I could divide (780-15) by 16, the number of squares I want.
That isn't working, and the next step of this project is to have a button where the user could input any number of squares for the row/column and have either a larger or smaller squared grid STILL ON the 780x780 square. Does anyone have any ideas? I'm pretty stumped.
$(document).ready(function() {
var original = 16;
for (var y = 0; y < original * original; y++) {
$(".squares").width((780 - 15) / original);
$(".squares").height((780 - 17) / original);
$("<div class='squares'></div>").appendTo('#main');
}
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
});
function gridq() {
$('.squares').removeClass('hover');
$('div').remove('.squares');
var newgrid = prompt("How many squares on each side?");
var widthscreen = 192;
if (newgrid > 0) {
for (var x = 0; x < newgrid * newgrid; x++) {
$(".squares").width(widthscreen / newgrid);
$(".squares").height(widthscreen / newgrid);
$("<div class='squares'></div>").appendTo('#main');
}
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
}
}
#main {
height: 780px;
width: 780px;
background-color: antiquewhite;
position: relative;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id=main>
</div>
<button onclick="gridq()">Go Again!</button>
Try this snippet? Grid initialisation is set in the grid() function and then called later when necessary. The width is set dynamically to the 16th square's right side.and the remaining squares fill out as necessary.
var wide = (780 - 15) / 16,
tall = (780 - 17) / 16; // set the square dimensions. this can be incorporated into the grid() function with 16 replaced by 'original'
function grid(x, y) {
var original = x,
y = y;
$("#main").empty(); // empty and restart
$("#main").width(wide * (original + 1));
for (var i = 0; i < original * y; i++) {
$("<div class='squares'></div>").appendTo('#main');
}
var square = $(".squares");
square.width(wide);
square.height(tall);
var side = square.eq(original - 1).position().left + square.width() + 2; // tighten the #main width
$("#main").width(side);
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
}
grid(16, 16); // starting dimension
function gridq() {
$('.squares').removeClass('hover');
$('div').remove('.squares');
var newgrid = prompt("How many squares on each side?");
var widthscreen = 192;
if (newgrid > 0) {
grid(newgrid, newgrid);
}
}
#main {
background-color: antiquewhite;
position: relative;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id='main'>
</div>
<button onclick="gridq()">Go Again!</button>
just got beat to it...ill post this as it answers the question slightly differently and I feel is a little cleaner. Also I added in a width and a height prompt.
see the codepen here
As a side note...its good practice to make the names of your variables make sense. Also I find that breaking down your code problems into smaller more manageable chunks makes it seem less overwhelming...one step at a time :)
Enjoy and good luck!
$(document).ready(function() {
//declare the variables at the top of your functions...it enables us to change them later
var columnWidthCount = 16;
var columnHeightCount = 16;
function makeBoxes() {
//boxcount lets us set how many times we want the for loop to run...when we change the columns/rows later this variable will be updated
var boxCount = columnWidthCount * columnHeightCount;
//
for (var i = 0; i < boxCount; i++) { //loop through each box
//any code you place in here will execute each time we loop around
$("<div class='squares'></div>").appendTo('#main');
}
//we only want to declare this once so we place it after the loop
$(".squares").width((780 / columnWidthCount) - 2);
$(".squares").height((780 / columnHeightCount) - 2);
$('.squares').hover(
function() {
$(this).addClass('hover');
}
);
}
//fire the initial function
makeBoxes();
// fire function after click
$('button').on("click", function() {
$('div').remove('.squares');
var squaresHigh = prompt("How many squares high? (must be a number)");
var squaresWide = prompt("How many squares wide? (must be a number)");
//prompt returns a string...use parseInt to turn that number string into an integer
columnWidthCount = parseInt(squaresWide);
columnHeightCount = parseInt(squaresHigh);
makeBoxes();
});
});
#main {
height: 780px;
width: 780px;
background-color: antiquewhite;
position: relative;
font-size:0;
white-space:nowrap;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id=main>
</div>
<button>Go Again!</button>

Using two of the same javascripts

I've been trying to create a page with several before and after images (Using a slider to swap between the two).
However when I add the second piece of JavaScript code, it breaks the page. Even if I try to amend the (var) code to be unique from the previous script
In all honesty I don't quite understand what the JavaScript is doing which is why I'm probably unable to Google the solution. Any help would be appreciated, if you could try to explain in as much detail what I need to do and explain any specific terms that would help me develop further.
You can see all my code on the link (and below): http://codepen.io/sn0wm0nkey/pen/DakbA
var inkbox = document.getElementById("inked-painted");
var colorbox = document.getElementById("colored");
var fillerImage = document.getElementById("inked");
inkbox.addEventListener("mousemove",trackLocation,false);
inkbox.addEventListener("touchstart",trackLocation,false);
inkbox.addEventListener("touchmove",trackLocation,false);
function trackLocation(e)
{
var rect = inked.getBoundingClientRect();
var position = ((e.pageX - rect.left) / inked.offsetWidth)*100;
if (position <= 100) { colorbox.style.width = position+"%"; }
}
/* -----second JavaScript code---- */
var inkbox1 = document.getElementById("inked1-painted");
var colorbox1 = document.getElementById("colored1");
var fillerImage1 = document.getElementById("inked1");
inkbox1.addEventListener("mousemove",trackLocation,false);
inkbox1.addEventListener("touchstart",trackLocation,false);
inkbox1.addEventListener("touchmove",trackLocation,false);
function trackLocation(e1)
{
var rect1 = inked.getBoundingClientRect();
var position1 = ((e1.pageX - rect1.left) / inked1.offsetWidth)*100;
if (position1 <= 100) { colorbox1.style.width = position1+"%"; }
}
body { background: #113; }
div#inked-painted {
position: relative; font-size: 0;
-ms-touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
div#inked-painted img {
width: 100%; height: auto;
}
div#colored {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/colored-panel.jpg);
position: absolute;
top: 0; left: 0; height: 100%;
width: 50%;
background-size: cover;
}
div#inked-painted:hover {
cursor: col-resize;
}
/*-------- second css sheet --------- */
div#inked1-painted {
position: relative; font-size: 0;
-ms-touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
div#inked1-painted img {
width: 100%; height: auto;
}
div#colored1 {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 50%;
background-size: cover;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/colored-panel.jpg);
}
div#inked1-painted:hover {
cursor: col-resize;
}
<Div>
<div id="inked-painted">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/inked-panel.png" id="inked" alt>
<div id="colored"></div>
</div>
<p></p>
<div>
<div id="inked1-painted">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/inked-panel.png" id="inked1" alt>
<div id="colored1"></div>
</div>
Howard's solution works but can be improved even more to remove duplication.
Use classes instead of Ids
Find the elements inside the div that is receiving the mousemove instead of passing them in
Don't duplicate the CSS
function onMouseMove(e) {
var inked = this.getElementsByTagName("img")[0];
var colorbox = this.querySelector('.colored');
var rect = inked.getBoundingClientRect();
var position = ((e.pageX - rect.left) / inked.offsetWidth) * 100;
if (position <= 100) {
colorbox.style.width = position + "%";
}
}
function trackLocation(el) {
el.addEventListener("mousemove", onMouseMove, false);
el.addEventListener("touchstart", onMouseMove, false);
el.addEventListener("touchmove", onMouseMove, false);
}
var wrappers = document.querySelectorAll('.inked-painted');
for (var i = 0; i < wrappers.length; i++) {
trackLocation(wrappers[i]);
}
div.inked-painted {
position: relative;
font-size: 0;
-ms-touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
div.inked-painted img {
width: 100%;
height: auto;
}
.colored {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/colored-panel.jpg);
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 50%;
background-size: cover;
}
div.inked-painted:hover {
cursor: col-resize;
}
<div class="inked-painted">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/inked-panel.png" />
<div class="colored"></div>
</div>
<p></p>
<div class="inked-painted">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/inked-panel.png" />
<div class="colored"></div>
</div>
First, Java != JavaScript. They are two very different languages.
Second, your issue is that your second function is named the same as your first function. The second one essentially overwrites the first one, so the first doesn't exist any longer. Simply use a different name for your second function, and your code works just fine.
However, it would be better to find a way to reuse your first function, instead of having two almost identical functions.
Here is what you are doing with your JavaScript how it is currently written.
Declare and assign variables inkbox, colorbox, fillerImage
Add event handlers
Create a function in the global scope by the name of trackLocation
Declare and assign variables inkbox1, colorbox1, fillerImage1
Add event handlers
Overwrite the trackLocation function in the global scope
All of this is being done synchronously, just as I have it listed here. So, when an event fires on inkbox, it calls the new function that overwrote the original.
Another problem that I see (unless you omitted some code) is you have some variables that are not defined, which will cause a problem within your function.
function trackLocation (e) {
// inked is undefined
var rect = inked.getBoundingClientRect();
// inked is undefined
var position = ((e.pageX - rect.left) / inked.offsetWidth)*100;
if (position <= 100) { colorbox.style.width = position+"%"; }
}
You'll need to rewrite your function to accept local variables like this:
function trackLocation (e, inked, colorbox) {
var rect = inked.getBoundingClientRect();
var position = ((e.pageX - rect.left) / inked.offsetWidth)*100;
if (position <= 100) { colorbox.style.width = position+"%"; }
}
Now this one function can be reused in all of your event handlers, like this:
function trackLocation (e, inked, colorbox) {
var rect = inked.getBoundingClientRect();
var position = ((e.pageX - rect.left) / inked.offsetWidth)*100;
if (position <= 100) { colorbox.style.width = position+"%"; }
}
var inkbox = document.getElementById("inked-painted");
var colorbox = document.getElementById("colored");
var fillerImage = document.getElementById("inked");
inkbox.addEventListener("mousemove", function (e) { trackLocation(e, inkbox, colorbox); });
inkbox.addEventListener("touchstart", function (e) { trackLocation(e, inkbox, colorbox); });
inkbox.addEventListener("touchmove", function (e) { trackLocation(e, inkbox, colorbox); });
var inkbox1 = document.getElementById("inked1-painted");
var colorbox1 = document.getElementById("colored1");
var fillerImage1 = document.getElementById("inked1");
inkbox1.addEventListener("mousemove", function (e) { trackLocation(e, inkbox1, colorbox1); });
inkbox1.addEventListener("touchstart", function (e) { trackLocation(e, inkbox1, colorbox1); });
inkbox1.addEventListener("touchmove", function (e) { trackLocation(e, inkbox1, colorbox1); });

Categories