Hello Stackoverflow Users, so I am making a game with HTML, I have to eat berries, but when I collect them, the more I collect (the max is 5), the more offset the extra body parts add to all of the body parts (minus the main one).
I have tried changing offset with the variables and loop I used, but nothing worked, no matter the math operator.
All of jQuery code:
// Null Variables \\
/* These variables have no value. */
var bound;
var newFood;
var horizontalMatch;
var vertialMatch;
// Main Variables \\
/* These variables keep values in store. */
var background = $(".game-background");
var player = $(".game-player");
var verticalNum = 0;
var horizontalNum = 0;
var score = 0;
var speed = 20;
var updatePos = 0;
var numOfSnakes = 0;
var snakesArray = [];
// Main Functions \\
/* These are all of the function being called, and created. */
updateSnakeCSS = function (snakes) {
if (snakes.length > -1) {
//for (var i = 0; i < snakes.length; i++) {
console.log(snakes[numOfSnakes - 1]);
$("." + snakes[numOfSnakes - 1]).css("position", "absolute");
$("." + snakes[numOfSnakes - 1]).css("left", player.offset().left - 20);
$("." + snakes[numOfSnakes - 1]).css("top", player.offset().top);
$("." + snakes[numOfSnakes - 1]).css("border", "black");
$("." + snakes[numOfSnakes - 1]).css("border-style", "outset");
$("." + snakes[numOfSnakes - 1]).css("border-width", 2 + "px");
$("." + snakes[numOfSnakes - 1]).css("width", player.width());
$("." + snakes[numOfSnakes - 1]).css("height", player.height());
$("." + snakes[numOfSnakes - 1]).css("background-color", "red");
//}
}
};
addSnake = function (snakes) {
if (numOfSnakes < 5) {
var body = document.getElementsByTagName("body")[0];
var newBodyPart = document.createElement("div");
newBodyPart.className = "game-player" + numOfSnakes;
body.appendChild(newBodyPart);
snakes.push("game-player" + numOfSnakes);
console.log(updatePos);
numOfSnakes++;
}
};
updateScore = function () {
score++;
$(".game-scoreboard").text("Berries: " + score);
};
createFood = function ($parentDiv) {
if (newFood == null) {
var x = WMath.random(220, background.width() * 1.5 - 100);
var y = WMath.random(100, background.height());
var body = document.getElementsByTagName("body")[0];
newFood = document.createElement("div");
newFood.className = "game-food";
body.appendChild(newFood);
$(".game-food").css("width", player.width() / 2);
$(".game-food").css("border", "black");
$(".game-food").css("border-style", "outset");
$(".game-food").css("border-width", 1 + "px");
$(".game-food").css("height", player.width() / 2);
$(".game-food").css("background-color", "red");
$(".game-food").css("position", "absolute");
$(".game-food").css("left", x);
$(".game-food").css("top", y);
}
};
var WMath = {
random: function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive
},
};
var WObject = {
isTouching: function ($div1, $div2) {
var x1 = $div1.offset().left;
var y1 = $div1.offset().top;
var h1 = $div1.outerHeight(true);
var w1 = $div1.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $div2.offset().left;
var y2 = $div2.offset().top;
var h2 = $div2.outerHeight(true);
var w2 = $div2.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
console.log("Touching WObject");
newFood = null;
createFood(document.body);
updateScore();
addSnake(snakesArray);
updateSnakeCSS(snakesArray);
speed += 2;
$div2.remove();
return true;
},
};
createFood(document.body);
$(document).keyup(function (e) {
var key = e.keyCode || e.which;
const keys = {
UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,
};
if (key === keys.UP && verticalNum > 0 && !String(verticalNum).includes("e")) {
verticalNum -= speed;
if (verticalNum < 0) {
verticalNum = 0;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("top", player.offset().top + i * 23 + updatePos);
$("." + snakesArray[i]).css("left", player.offset().left + updatePos);
}
}
$(".game-player").css("top", verticalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.DOWN && verticalNum < 475.8000000000002) {
verticalNum += speed;
if (verticalNum > 475.8000000000002) {
verticalNum = 475.8000000000002;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("top", player.offset().top - i * 23 - updatePos);
$("." + snakesArray[i]).css("left", player.offset().left - updatePos);
}
}
$(".game-player").css("top", verticalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.LEFT && horizontalNum > 0 && !String(horizontalNum).includes("e")) {
horizontalNum -= speed;
if (horizontalNum < 0) {
horizontalNum = 0;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("left", player.offset().left + i * 23 + updatePos);
$("." + snakesArray[i]).css("top", player.offset().top + updatePos);
}
}
$(".game-player").css("left", horizontalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.RIGHT && horizontalNum < 475.8000000000002) {
horizontalNum += speed;
if (horizontalNum > 475.8000000000002) {
horizontalNum = 475.8000000000002;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("left", player.offset().left - i * 23 - updatePos);
$("." + snakesArray[i]).css("top", player.offset().top - updatePos);
}
}
$(".game-player").css("left", horizontalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GAME</title>
<style>
.game-background {
background-color: lightgray;
width: 500px;
height: 500px;
position: absolute;
top: 55px;
left: 200px;
border: black;
border-style: solid;
border-width: 10px;
}
.game-player {
background-color: blue;
width: 20px;
height: 20px;
position: relative;
top: 0px;
left: 0px;
border: black;
border-style: inherit;
border-width: 2px;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="game-scoreboard">Berries: 0</p>
<div class="game-background">
<div class="game-player"></div>
</div>
<script>
// The Script shown in the JavaScript
</script>
</body>
</html>
It's because of:
speed += 2;
Remove it and it will work fine.
As you're using speed in calculating the verticalNum and horizontalNum everytime, so it increments it with 2 each time, giving a wrong position.
The output after removing it:
Related
I want to detect a collision between two divs and I've tried to do that using the offsetLeft and offsetTop of each one of the divs and by using getBoundingClientRect(). But none of these work.
Is there a way I can get the exact coordinates in which these two elements touch?
const bigDiv = document.querySelector(".big")
const blue = document.querySelector(".blue")
const startBtn = document.querySelector("button")
const red = document.querySelector(".red")
const bigDivDimensions = bigDiv.getBoundingClientRect();
let speed = 5;
//let counter = 0;
let bigDivLeft = bigDivDimensions.left;
startGame();
function random() {
return Math.floor(Math.random() * (bigDivDimensions.width - 40));
}
function startGame() {
//let randomSnake = Math.floor(Math.random()*(bigDivDimensions.width-40));
//let randomApple = Math.ceil(Math.random()*(bigDivDimensions.width -40));
blue.style.left = random() + "px"
blue.style.top = random() + "px"
red.style.left = random() + "px"
red.style.top = random() + "px"
}
function move(e) {
let blueX = blue.offsetLeft;
let blueY = blue.offsetTop;
let key = e.keyCode;
if (key !== 37 && key !== 38 && key !== 39 && key !== 40) {
return
} else if (key === 37 && blueX > 3) {
blueX -= speed;
} else if (key === 38 && blueY > 3) {
blueY -= speed;
} else if (key === 39 && blueX < (bigDivDimensions.width - 25)) {
blueX += speed;
} else if (key === 40 && blueY < (bigDivDimensions.height - 23)) {
blueY += speed;
}
blue.style.left = blueX + "px";
blue.style.top = blueY + "px";
colision(blueX, blueY)
}
function colision(blueX, blueY) {
/* let redX = red.offsetLeft;
let redY = red.offsetTop;
if(redY === blueY || redX == blueX){console.log("hit")} */
let redRect = red.getBoundingClientRect();
let blueRect = blue.getBoundingClientRect();
if ((redRect.top < blueRect.bottom) || (redRect.bottom < blueRect.top) || (redRect.right > blueRect.left) || (redRect.left < blueRect.right)) {
console.log("hit")
}
}
startBtn.addEventListener("click", startGame)
document.addEventListener("keydown", move)
.big {
width: 400px;
height: 400px;
outline: 1px solid red;
margin: 0 auto;
position: relative;
}
.blue {
width: 20px;
height: 20px;
background: blue;
position: absolute;
}
.red {
width: 20px;
height: 20px;
background: red;
position: absolute;
}
<button type="button">Start Game</button>
<div class="big">
<div class="blue"></div>
<div class="red"></div>
</div>
codepen
Two rectangles do collide when their
horizontal side and vertical side
overlap.
Consider the following answer: Checking for range overlap
// l1 (line 1) --> [x1, x2]
// l2 (line 2) --> [x1, x2]
function checkOverlap(l1, l2) {
return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0) ? true : false;
}
Check collision with range overlap for the x-side and y-side:
// Rectangle a --> [[x1, x2], [y1, y2]]
// Rectangle b --> [[x1, x2], [y1, y2]]
function collide(a, b) {
return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1]));
}
Spoiler
SVG-Example
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var width = 200;
var height = 200;
svg.setAttribute("width", width);
svg.setAttribute("height", height);
document.body.appendChild(svg);
function createRect(svg, width, height, x, y, style, id) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("width", width);
rect.setAttribute("height", height);
rect.setAttribute("x", x);
rect.setAttribute("y", y);
rect.setAttribute("style", style);
rect.setAttribute("id", id);
svg.appendChild(rect);
}
function createSquare(svg, side, x, y, style, id) {
createRect(svg, side, side, x, y, style, id);
}
function getRandomNumber(a, b) {
return Math.round(Math.random() * (b - a)) + a;
}
function createRandomSquare(svg, xRange, yRange, side, style, id) {
var x = getRandomNumber(xRange[0], xRange[1]);
var y = getRandomNumber(yRange[0], yRange[1]);
createSquare(svg, side, x, y, style, id);
return [
[x, x + side],
[y, y + side]
];
}
function checkOverlap(l1, l2) {
return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0) ? true : false;
}
// [[x1, x2], [y1, y2]]
function collide(a, b) {
return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1]));
}
function getCoordinates(arr) {
return {
"top-left": [arr[0][0], arr[1][0]],
"top-right": [arr[0][1], arr[1][0]],
"bottom-left": [arr[0][1], arr[1][1]],
"bottom-right": [arr[0][0], arr[1][1]]
}
}
function run() {
var bs = document.getElementById("blueSquare");
var rs = document.getElementById("redSquare");
var output = document.getElementById("output");
output.innerHTML = "";
if (bs !== null && rs !== null) {
var parent = bs.parentNode;
parent.removeChild(bs);
parent.removeChild(rs);
}
var side = 30;
var blueSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)], side, "fill:blue", "blueSquare");
var redSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)], side, "fill:red", "redSquare");
var output1 = "Collision? " + collide(blueSquare, redSquare);
var output2 = "Blue square: " +
JSON.stringify(getCoordinates(blueSquare));
var output3 = "Red square: " + JSON.stringify(getCoordinates(redSquare));
output.innerHTML = output1 + "<br>" + output2 + "<br>" + output3 + "<br>";
}
var button = document.createElement("button");
button.setAttribute("id", "button");
button.textContent = "Run";
button.addEventListener("click", run);
document.body.appendChild(button);
svg {
border: 1px solid;
}
<div id="output"></div>
There are some runner(animation-image) in my program which move from position x to y when clicked on start button, i want to add a (reverse)button on completion that when clicked on that the image moves from y to x.
Here is the link of my js-fiddle: https://jsfiddle.net/o6egL4qr/
I have added the reverse button but when clicked on that the image doesn't move at all.
class raceManager {
raceCount = 0;
races = [];
addRace() {
var mainContainer = document.getElementById('mainContainer');
mainContainer.appendChild(document.createElement('br'));
var race = new raceClass(this.raceCount);
this.races.push(race);
this.raceCount++;
}
}
class raceClass {
runners = [];
count;
runnerCount = 0;
raceDiv = document.createElement('div');
raceNum = document.createElement('div');
startRaceButton = document.createElement('input');
addRunnerButton = document.createElement('input');
revRaceButton = document.createElement('input');
tableDiv = document.createElement('div');
tableNum = document.createElement('div');
startInterval;
startTime;
revStartTime;
reverseInterval;
constructor(number) {
// store the race no.
this.count = number;
// delcare the race div id
this.raceNum.id = 'raceNum' + this.count;
// delcare the table div id
this.tableNum.id = 'tableNum' + this.count;
// Add raceDiv to the race
document.getElementById('races').appendChild(this.raceDiv);
// Add tableDiv to the race
document.getElementById('tables').appendChild(this.tableDiv);
this.applyDivProperty();
this.initializeButtons();
}
applyDivProperty() {
// apply properties to the tableNum
this.tableNum.style.display = "inline-block";
// apply properties to the raceDiv
this.raceDiv.id = "Race" + this.count;
document.getElementById(this.raceDiv.id).classList.add("raceDivClass");
this.raceDiv.appendChild(this.raceNum);
document.getElementById(this.raceNum.id).innerHTML = '<p>Race: ' + this.count + '</p>';
// append the add race button
this.raceDiv.appendChild(this.addRunnerButton);
// apply properties to the tableDiv
this.tableDiv.id = "Table" + this.count;
document.getElementById(this.tableDiv.id).classList.add("tableClass");
this.tableDiv.appendChild(this.tableNum);
document.getElementById(this.tableNum.id).innerHTML = '<p>Table: ' + this.count + '</p>';
}
initializeButtons() {
// initialize add runner button
this.addRunnerButton.type = 'Button';
this.addRunnerButton.value = 'Add Runner';
this.addRunnerButton.id = 'AddRunner' + this.count;
this.addRunnerButton.onclick = this.addRunner.bind(this);
// initialize start race buttton
this.startRaceButton.type = 'Button';
this.startRaceButton.value = 'Start Race';
this.startRaceButton.id = "startRaceButton" + this.count;
this.startRaceButton.onclick = this.startRace.bind(this);
// initialize reverse race buttton
this.revRaceButton.type = 'Button';
this.revRaceButton.value = 'Reverse Race';
this.revRaceButton.id = "revRaceButton" + this.count;
this.revRaceButton.onclick = this.revRace.bind(this);
}
addRunner() {
var track = new Runner(this); //Initialize the runner object
this.runners.push(track); //Store the runner object in runners array of Race class
if (this.runnerCount > 0) {
// append the start race button
this.raceDiv.appendChild(this.startRaceButton);
}
this.runnerCount++;
}
startRace() {
this.startTime = Date.now();
this.startInterval = setInterval(() => {
this.runners.forEach(function(element) {
element.animate();
});
document.getElementById(this.startRaceButton.id).disabled = "true";
document.getElementById(this.addRunnerButton.id).disabled = "true";
}, 50);
}
stop() {
clearInterval(this.startInterval);
// append the start race button
this.raceDiv.appendChild(this.revRaceButton);
}
revRace() {
this.revStartTime = Date.now();
this.reverseInterval = setInterval(() => {
this.runners.forEach(function(element) {
element.animateReverse();
});
document.getElementById(this.revRaceButton.id).disabled = "true";
}, 50);
}
stopRev() {
clearInterval(this.reverseInterval);
}
}
class Runner {
count = 0;
parent;
track;
sprite;
timeTaken;
trackWidth;
element;
speed;
table;
printCount = 1;
stepCount = 1;
trackNum;
tbl;
lastStep;
constructor(race) {
// initialize the divs
this.parent = race;
this.track = document.createElement('div');
this.sprite = document.createElement('div');
this.table = document.createElement('table');
// assigns #id to table and track corresponding with parent div.
this.table.id = race.tableNum.id + '_Table_' + this.parent.runnerCount;
this.track.id = race.raceNum.id + '_Track_' + this.parent.runnerCount;
this.createUI();
this.timeTaken = ((Math.random() * 5) + 3);
this.speed = this.trackWidth / (this.timeTaken * 1000);
console.log(this.trackWidth, this.timeTaken);
console.log(this.timeTaken * 100);
}
createUI() {
this.count = this.parent.runnerCount;
this.createTable();
this.createTrack();
this.createSprite();
}
createTable() {
var parentDiv1 = document.getElementById(this.parent.tableNum.id);
parentDiv1.appendChild(this.table);
this.table.setAttribute = "border"
this.table.border = "1";
document.getElementById(this.table.id).classList.add("tableClass");
this.tbl = document.getElementById(this.table.id);
this.addRow("Track " + (this.count + 1), "");
this.addRow("Time", "Distance");
}
addCell(tr, val) {
var td = document.createElement('td');
td.innerHTML = val;
tr.appendChild(td)
}
addRow(val_1, val_2) {
var tr = document.createElement('tr');
this.addCell(tr, val_1);
this.addCell(tr, val_2);
this.tbl.appendChild(tr)
}
createTrack() {
var parentDiv = document.getElementById(this.parent.raceNum.id);
parentDiv.appendChild(this.track);
this.track.appendChild(this.sprite);
document.getElementById(this.track.id).classList.add("trackClass");
this.trackWidth = this.track.getBoundingClientRect().width;
}
createSprite() {
this.sprite.id = this.track.id + "_Runner";
document.getElementById(this.sprite.id).classList.add("spriteClass");
this.element = document.getElementById(this.sprite.id);
}
animate() {
// declare time variables
var timeNow = Date.now();
var timespent = timeNow - this.parent.startTime;
var diff = Math.floor(this.timeTaken * 100);
// step is position of sprite.
var step = timespent * this.speed;
// Print table for all tracks with 10 laps.
if ((Math.round(timespent / 50) * 50) == (Math.round(((diff - 25) * this.printCount) / 50) * 50)) {
this.addRow(this.printCount + ": " + timespent, (Math.floor(step)));
this.printCount++;
}
// check condition to stop
if (step > this.trackWidth - 23) {
document.getElementById(this.parent.raceNum.id).innerHTML += 'Winner: Runner' + (this.count + 1);
this.parent.stop();
}
this.element.style.left = step + 'px';
// ------------sprite animation----------------
// start position for the image slicer
var position = (3 - (Math.floor(step / 6.5) % 4)) * 25;
// we use the ES6 template literal to insert the variable "position"
this.element.style.backgroundPosition = `${position}px 0px`;
}
animateReverse() {
// declare time variables
var timeNow = Date.now();
var timespent = timeNow - this.parent.revStartTime;
var diff = Math.floor(this.timeTaken * 100);
console.log(this.count + " position of step " + this.element.style.left);
while (this.stepCount < 2) {
this.lastStep = parseFloat(this.element.style.left);
this.stepCount++;
}
console.log(this.count + " this is lastStep " + this.lastStep);
// step is position of sprite.
var step = this.lastStep - (this.speed * timespent);
// Print table for all tracks with 10 laps.
if ((Math.round(timespent / 50) * 50) == (Math.round(((diff - 25) * this.printCount) / 50) * 50)) {
this.addRow(this.printCount + ": " + timespent, (Math.floor(step)));
this.printCount++;
}
// check condition to stop
if (step < 25) {
document.getElementById(this.parent.raceNum.id).innerHTML += 'Winner: Runner' + (this.count + 1);
this.parent.stopRev();
}
this.element.style.left = step + 'px';
// ------------sprite animation----------------
// start position for the image slicer
//var position = (3 - (Math.floor(step / 6.5) % 4)) * 25;
//this.element.style.backgroundPosition = position + 'px 0px';
}
}
manager = new raceManager();
#tableContainer {
float: left;
}
#addRaces {
text-align: center;
}
.raceDivClass {
margin: 1% auto;
width: 60%;
text-align: center;
border: 1px solid;
}
.tableClass {
text-align: center;
border: 1px solid;
margin: 5px;
float: left;
}
.trackClass {
background-color: black;
height: 30px;
width: 98%;
margin: 1%;
position: relative;
}
.spriteClass {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAeCAYAAADAZ1t9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASwSURBVGhD7Zq/axRBFMfv9u4MxATUSgsVm3QWigYbexuxUkiaKIqNoIUiwRSJoJLCxpSCaJoEYimo/4AgQVRIZxdBEIREYwzc5X74vndvlrm5mdnZ3dm9oPnAsDubu52Z93373pvNFQsJOXO9NUKHsU4vZPH90+IXPt/FA2kEmqbDTKcX8pza7K5I/vAtEJghge7zeSrwlDYbtYlmfWuILxWC8uBmUNoz/784wY4WaPRq9SGJcY+7Mt7GEOzUkB0pkGHi4Ci1K53TEK8h7tTE+pPywL6b3JXJQqBcQ7arQwR87AE34ElPUsPE1ZapODsErFHnnD7AfVWb9oylFYjVFcKoQuQC5kD55hB3Qxrbf17RYbHT+/fpCXGSOEmEaYcevofwhkRxXM0/VCi8azXr3+q1Xw8+LRxZ4cte4PneoHaQ2iVck0gVThVbyOhSRM9YOoFMyR9eW6KmLkAGYW6Vmjx47AViUfSkPC5V9p7nS23q1Z9zH+b33+KuF9iAOocUa0lcKFjubQJ2h51D5zbmIAVM9gc1mzgAE0kdFlFaq+JkQYQBV+FYOYoDGy9Tw3dgQ7QxnUBQUHxAtJfUhqllDhbWam4f525mJDCgMynufZFa13d6BILHsOeEjS6PUjMNtsRHFXgExI2V0PN6egiEkTzFMdlJgM/3zMd1H2Tzhjlqa53TLhLFbsvep9Cob70uFsuffbxJoHWZcq1A5CCZyDUZ7gtxotKDCsafdRHIZSFe9j9wBl1xoIJSuxhUVpIK5eB0JiILHo29EouDtVmLBF4IKjIbWOQkfzYVruENn+ESXFe+upBJeDMQVfWiyXQ5fFQV57oQLyLJL0VlsAfi06yJyhMuIOci7Efdqy0ENzxxonVFI22IY0NDHN1mykaX+nHAmKbw1qhtLLVaze8U1o6Jv9OmdaEYlI1lsLQGGVGwmMKbKZ8KXHIQxnUJn062CgVSFmQTRjySpr8n2nlb3lxTztl8W6+u3x0YOlylrpij1Vi0Hl3uxNx/U9MWIYSPtwZxclukSG2B4qreOTV+3skzBBgbuafVrJ0sVYbO8eUe4r5FMAgEbEnbSSC2l/p0grgRB1jHDGKqjt019kkwvoid4okS4D7O+Qji4MmxiQMonI2cGP/qYwMbt6LSAXFEzpCbyYaJcxuKBAwWJQ5EwATCTScLBeUhVGKRTIWBCgQsVYavcdcF8UZEnVveYPwXfIwNBMJCdF/GNeEZCFnahMzX1A0dgEi6MJALigP1SyiMCdu9wZH7sZBzkGpM5zcBljAZGdNPX964UAhKt0vlwbN8SQs2p/Xq2lTSfzU4hvK0OUily4b0PV1etI4Z+SbBFYMBrIPjO1QuT1N+GedLbVC1FYM9Hyk31fgScHYYE5JhD1Dz/r+fKPoqEJAMILAa1VRaU+HwaPnZwBR3vWJwJCDCUSonsKERKHJMrwLFAYbSbUwRyujanawMZfBikPXTEzvCgKhXPZmhe+/W2ZCuTWXpxQbgyWGFmhGILLb8p6V/AmnKa+Qd3783cCDz0JaGvgmEX4jyaRu8W6N8NM/dPGlvvvk8T5ye2r7mIIQ5PEl5/pyXc4FzIeOLZOMWCn8Bh1eBvOSZzIIAAAAASUVORK5CYII=');
position: absolute;
height: 30px;
width: 25px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="mainContainer">
<div id="addRaces">
<input type="Button" value="Add Race" onclick="manager.addRace()">
</div>
<div id="races">
</div>
<br>
</div>
<div id="tableContainer">
<div id="tables"></div>
</div>
</body>
</html>
I expect it to move from y to x after clicking the reverse button, but it is not moving.
When you run the reverse function the elements are no longer referencing the dom elements.
I am actually not sure why that is, maybe someone else can chime in.
Anyway, this will fix your problem:
Replace this.element.style.left = step + 'px';
With: document.getElementById(this.element.id).style.left = step + 'px';
I have a nav menu that has got a lot ul in ul tag so I have to change where it is opened that right side or left side.
And if main menu is bigger than screenwidth then they must be hamburger menu that they are not fit on screen.
I created this js code. It is working and stable.
something that requires attention.
1- there is a class that's name is ".has-children" in my design
2- if screen bigger than 1070, it can be shown
#media (max-width: 1070px)
so You may need to change relating to your code this code in my js
if (screenWidth > 1070)
because it will be start after 1070
<script>
$(document).ready(function () {
var menu = $("#nav").find("ul:first");
var navbarSticky = $(".navbar.navbar-sticky");//navbar-sticky
var menubarLeft = $(".site-branding");//logo left
var menubarRight = $(".toolbar");//toolbar right
var right = parseInt(menubarRight.css("right").replace("px", "")); // right space of right toolbar
var oldMenu = menu.html(); //necessary for reset it that configured
var minWidthSiteMenu = 1070;
var screenWidth = $(window).outerWidth();
if (screenWidth > minWidthSiteMenu) {
menu.html(oldMenu);
setMenuPosition();
}
$(window).resize(function () {
var screenWidth = $(window).outerWidth();
if (screenWidth > minWidthSiteMenu) {
menu.html(oldMenu);
setMenuPosition();
}
});
function setMenuPosition() {
var menuFixed = false;
var humburgerMenuArray = new Array();
var counter = 0;
for (var i = 0; i < 1; i++) {
var result = navbarSticky.width() - menubarLeft.width() - menubarRight.width() - menu.width() - right - 70;// 70 for icon of humburger menu
if (result < 0) {
//console.log(menu.find("li").last().html());
humburgerMenuArray[counter] = $("#nav").find("ul:first > li:last").html();
counter++;
$("#nav").find("ul:first > li:last").remove();
result = navbarSticky.width() - menubarLeft.width() - menubarRight.width() - menu.width() - right;
menu.css("margin-left", menubarLeft.width() + result / 2 + 20 + "px");
i = -1;
menuFixed = true;
}
else {
menu.css("margin-left", menubarLeft.width() + result / 2 + 20 + "px");
i = 1;
}
//console.log(menu);
//console.log(result);
}
if (menuFixed) {
var imageHamburger = "<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-menu'><line x1='3' y1='12' x2='21' y2='12'></line><line x1='3' y1='6' x2='21' y2='6'></line><line x1='3' y1='18' x2='21' y2='18'></line></svg>";
var humburgerMenu = "<li><a href='javascript:void(0)' style='padding-top: 26px !important;' class='menu-toggle'>" + imageHamburger + "</a>";
humburgerMenu += "<ul class='sub-menu'>";
var counterHumburger = humburgerMenuArray.length;
humburgerMenuArray.forEach(function () {
var hasChildren = humburgerMenuArray[counterHumburger - 1].search("sub-menu");
if (hasChildren === -1) {
humburgerMenu += "<li>";
}
else {
humburgerMenu += "<li class='has-children'>";
}
humburgerMenu += humburgerMenuArray[counterHumburger - 1];
humburgerMenu += "</li>";
//console.log(humburgerMenuArray[counterHumburger - 1]);
counterHumburger--;
});
humburgerMenu += "</ul>";
humburgerMenu += "</li>";
menu.append(humburgerMenu);
//console.log(menu.html());
}
$("#nav").css("visibility", "visible");
//set setSubMenuPositionLeftRightSide
setSubMenuPositionLeftRightSide();
}
/* Menu Position Left or Right Side */
var style = document.createElement('style');
style.innerHTML = "li.left-arrow > a::after {border-left: 0 solid !important;border-right: .32em solid !important;}";
document.head.appendChild(style);
var menuLeftPositionIsOk = false;
var nextMenuPositon = 0;
var zIndex = 10000;
function setSubMenuPositionLeftRightSide() {
var screenWidth = $(window).outerWidth(); //outerWidth is very important because it is not contain to spage of scroll that overflow
//console.log(screenWidth);
//reset all rel attr - its name is rel-menu-position
$("#nav > ul").each(function (i) {
$(this).find("ul").removeAttr('rel-menu-position');
});
$("#nav > ul > li > ul > li").hover(function (e) {
menuLeftPositionIsOk = false;
//nextMenuPositon = 0; // it is not necessary
zIndex = 10000;
}, function (c) { });
var menuId = 0;
if (screenWidth > minWidthSiteMenu) {
$(".has-children").hover(function (e) {
zIndex++;
$(e.currentTarget).css("zIndex", zIndex);
//console.log($(e.currentTarget).css("zIndex"));
menuPositionCalculate(e, screenWidth);
},
function (c) {
menuLeftPositionIsOk = false;//this is very important for other sub menu that you have change it...
$(c.currentTarget).css("zIndex", 'auto');
$(c.currentTarget).removeClass("left-arrow");
//console.log("menu is closed");
});
}
}
function menuPositionCalculate(e, screenWidth) {
var menuPosition = $(e.target).offset().left + $(e.currentTarget).width() + $(e.currentTarget).find('ul').outerWidth();
//console.log("menuPosition " + menuPosition);
// 25px space left side
if (nextMenuPositon - $(e.currentTarget).find('ul').outerWidth() - 25 < 0) {
menuLeftPositionIsOk = false;
//console.log("RESET - left side - if " + menuPosition + " >> " + screenWidth);
}
if ($(e.currentTarget).find('ul').first().attr('rel-menu-position') === 'left') {
menuLeftPositionIsOk = true;
}
if ($(e.currentTarget).find('ul').first().attr('rel-menu-position') === 'right') {
menuLeftPositionIsOk = false;
}
// 25px space right side
if (menuPosition + 25 > screenWidth ||
menuLeftPositionIsOk ||
nextMenuPositon + 25 > screenWidth) {
menuPosition = $(e.target).offset().left + $(e.currentTarget).width() + $(e.currentTarget).find('ul').outerWidth();
menuLeftPositionIsOk = true;
nextMenuPositon = menuLeftSidePosition(e);
//console.log("left side if " + menuPosition + " >> " + screenWidth);
$(e.currentTarget).addClass("left-arrow");
$(e.currentTarget).find('ul').first().attr('rel-menu-position', 'left');
} else {
$(e.currentTarget).removeClass("left-arrow");
$(e.currentTarget).find('ul').first().attr('rel-menu-position', 'right');
}
}
function menuLeftSidePosition(e) {
//20px come over to parent menu
var menuPositionLeft = $(e.target).offset().left - $(e.currentTarget).find('ul').first().outerWidth() + 20;
$(e.currentTarget).find('ul').first().offset({ "left": menuPositionLeft });
return menuPositionLeft;
}
});
</script>
Im trying to create a program for one of my games(details not needed) nevertheless I can move around aside elements written in the code
<aside draggable="true" class="dragme" data-item="0">One</aside>
but if I create it at runtime(via button click) it gives me this error in the console
Uncaught TypeError: Cannot read property 'style' of undefined
Here is my full code anybody have ideas?
<!DOCTYPE HTML>
<html>
<head>
<style>
aside {
position: absolute;
left: 0;
top: 0;
width: 200px;
background: rgba(255, 255, 255, 1);
border: 2px solid rgba(0, 0, 0, 1);
border-radius: 4px;
padding: 8px;
}
.second {
left: 100px;
top: 100px;
}
body, html {
min-height: 100vh;
}
body{
width:700px;
height:700px;
}
</style>
</head>
<body ondragover="drag_over(event)" ondrop="drop(event)">
<div class="ControlPanel">
<button onclick="CreateNew('item1')">Item1</button>
</div>
<aside draggable="true" class="dragme" data-item="0">One</aside>
<script>
var dataNum = 0;
function CreateNew(item){
if(item == "item1"){
dataNum += 1;
var asi = document.createElement("ASIDE");
asi.setAttribute("draggable",true);
asi.setAttribute("class","dragme second");
asi.setAttribute("data-item",dataNum);
asi.setAttribute("style","left: 347px; top: 82px;");
document.body.appendChild(asi);
}
}
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) + ',' + event.target.getAttribute('data-item'));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementsByClassName('dragme');
dm[parseInt(offset[2])].style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
dm[parseInt(offset[2])].style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
event.preventDefault();
return false;
}
var dm = document.getElementsByClassName('dragme');
for (var i = 0; i < dm.length; i++) {
dm[i].addEventListener('dragstart', drag_start, false);
document.body.addEventListener('dragover', drag_over, false);
document.body.addEventListener('drop', drop, false);
}
</script>
</body>
</html>
You are registering the event listener only once during the page load. Therefore, when you create a new element, you need to re-register the events for the newly created elements too.
<script>
var dataNum = 0;
function CreateNew(item){
if(item == "item1"){
dataNum += 1;
var asi = document.createElement("ASIDE");
asi.setAttribute("draggable",true);
asi.setAttribute("class","dragme second");
asi.setAttribute("data-item",dataNum);
asi.setAttribute("style","left: 347px; top: 82px;");
document.body.appendChild(asi);
registerDragMe(); // --> Add this
}
}
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) + ',' + event.target.getAttribute('data-item'));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementsByClassName('dragme');
dm[parseInt(offset[2])].style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
dm[parseInt(offset[2])].style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
event.preventDefault();
return false;
}
// create a wrapper function
function registerDragMe(){
var dm = document.getElementsByClassName('dragme');
for (var i = 0; i < dm.length; i++) {
dm[i].addEventListener('dragstart', drag_start, false);
document.body.addEventListener('dragover', drag_over, false);
document.body.addEventListener('drop', drop, false);
}
}
registerDragMe();
</script>
Working example : https://jsfiddle.net/jcLjr70y/
var start_mouse_y = 0;
var scroll_offset = 0;
function SET_SCROLL(e){
document.getElementById("online_list_scroll").draggable = true;
start_mouse_y = e.clientY;
}
function ADJUST_SCROLL(e){
dont_pass = (412 - set_scroll_height);
mouse_y = e.clientY;
scroll_top = parseInt(document.getElementById("online_list_scroll").style.top);
scroll_offset = (mouse_y - scroll_top) + 46;
new_top = scroll_top + (mouse_y - start_mouse_y);
document.getElementById("DEBUG").innerHTML = "my: "+mouse_y+"<br>new_top: "+new_top+"<br>scroll_offset: "+scroll_offset+"<br>scroll_top: "+scroll_top;
if(new_top <= 0){
document.getElementById("online_list_scroll").style.top = 0+"px";
}else if(new_top >= dont_pass){
document.getElementById("online_list_scroll").style.top = dont_pass+"px";
}else{
document.getElementById("online_list_scroll").style.top = new_top+"px";
}
scroll_bottom = set_scroll_height + new_top;
scroll_percent = scroll_bottom / 412;
online_show = (document.getElementById("online_list").scrollHeight - 412) * scroll_percent;
online_show = Math.round(online_show);
document.getElementById("online_list").scrollTop = online_show;
}
var SCROLL_ON = 0;
document.onmouseup = function(){ SCROLL_ON = 0; };
document.onmousemove = function(event){ if(SCROLL_ON == 1){ADJUST_SCROLL(event);} };
javascript ^^
<div style="float: left; width: 13px; position: relative; height: 412px;">
<div id="online_list_scroll" style="width: 5px; position: absolute; top: 0px; left: 4px; border-radius: 4px; background-color: #3f3f3f; height: 15px;" onmousedown="if(SCROLL_ON == 0){ SET_SCROLL(event); SCROLL_ON = 1; }"></div>
</div>
html^^
i dont know why but the scroll bar scrolls at a very fast and unsteady flow rate. it works, but just jerks when scrolls up and down, jerk as in as u move one way it shoots that way quicker and quicker.
Thanks for any help, worked figuring out how to do this all night.
You have a problem with local var the following code works. Not made as a general thing, just repaired the code. Here you have the code with the comments where is the common mistake.
//first make sure you have defined with var the variables you need.
var start_mouse_y = 0;
var mouse_y = 0;
var scroll_offset = 0;
function SET_SCROLL(e) {
document.getElementById("online_list_scroll").draggable = true;
start_mouse_y = e.clientY;
// you need mouse_y to be initialized with start_mouse_y
mouse_y = start_mouse_y;
}
function ADJUST_SCROLL(e) {
var set_scroll_height = 0;
var dont_pass = (412 - set_scroll_height);
// here you set the last mouse_y to be start_mouse_y or else it would be
// a the first position of the mouse ( eg. 8 ) subtracted from the current ( eg. 50 )
// now remembering the last already added position (eg. 49) which is subtracted from
// the current (eg. 50 ) it works just fine
start_mouse_y = mouse_y;
mouse_y = e.clientY;
var scroll_top = parseInt(document.getElementById("online_list_scroll").style.top);
scroll_offset = (scroll_top- mouse_y ) + 46;
var new_top = scroll_top + (mouse_y- start_mouse_y);
console.log("my: " + mouse_y + "<br>new_top: " + new_top + "<br>scroll_offset: " + scroll_offset + "<br>scroll_top: " + scroll_top);
if(new_top <= 0) {
document.getElementById("online_list_scroll").style.top = 0 + "px";
} else if(new_top >= dont_pass) {
document.getElementById("online_list_scroll").style.top = dont_pass + "px";
} else {
document.getElementById("online_list_scroll").style.top = new_top + "px";
}
var scroll_bottom = set_scroll_height + new_top;
var scroll_percent = scroll_bottom / 412;
var online_show = (document.getElementById("online_list").scrollHeight - 412) * scroll_percent;
online_show = Math.round(online_show);
document.getElementById("online_list").scrollTop = online_show;
}
var SCROLL_ON = 0;
document.onmouseup = function() {
SCROLL_ON = 0;
};
document.onmousemove = function(event) {
if(SCROLL_ON == 1) {ADJUST_SCROLL(event);
}
};
Best regards,