I managed to get a div id = "box" to move in the browser with arrow keys. Now I want to make every div id = "box" with class .something to move also.
I have try loop over the code with querySelectorAll but the code always fail.
Can someone help me out? And tell me how to do it because now I feel lost totally. The code below works just with one div id
var box = document.getElementById("box");
document.addEventListener("keydown", function(event) {
var key = event.key;
var left = box.offsetLeft;
var top = box.offsetTop;
console.log("left: ", left);
console.log("top: ", top);
box.style.top = (top - step) + "px";
box.style.top = (top - step) + "px";
box.style.top = (top - step) + "px";
box.style.top = (top - step) + "px";
var step = 10;
switch (key) {
case "ArrowUp":
event.preventDefault();
box.style.top = (top - step) + "px";
break;
case "ArrowDown":
event.preventDefault();
box.style.top = (top + step) + "px";
break;
case "ArrowLeft":
box.style.left = (left - step) + "px";
break;
case "ArrowRight":
box.style.left = (left + step) + "px";
break;
}
console.log("You pressed on: ", key);
});
Took a stab at fixing it.
Repl can be found here: https://repl.it/#PaulThomas1/FrightenedAgileBrain
document.addEventListener("keydown", function(event) {
var boxes = document.getElementsByClassName("box");
var key = event.key;
for(var i = 0; i < boxes.length; i++) {
var box = boxes[i];
var left = box.offsetLeft;
var top = box.offsetTop;
console.log("left: ", left);
console.log("top: ", top);
var step = 10;
switch (key) {
case "ArrowUp":
event.preventDefault();
box.style.top = (top - step) + "px";
break;
case "ArrowDown":
event.preventDefault();
box.style.top = (top + step) + "px";
break;
case "ArrowLeft":
box.style.left = (left - step) + "px";
break;
case "ArrowRight":
box.style.left = (left + step) + "px";
break;
}
console.log("You pressed on: ", key);
}
});
Because querySelector all will give you an array as a result, you can't just change it easily, you have to iterate over all of the objects.
var elements = document.querySelectorAll('.something');
document.addEventListener("keydown", function(event) {
var key = event.key;
var step = 10;
for(let el of elements){
let left = el.offsetLeft;
let top = el.offsetTop;
el.style.top = (top - step) + "px";
switch (key) {
case "ArrowUp":
event.preventDefault();
el.style.top = (top - step) + "px";
break;
case "ArrowDown":
event.preventDefault();
el.style.top = (top + step) + "px";
break;
case "ArrowLeft":
el.style.left = (left - step) + "px";
break;
case "ArrowRight":
el.style.left = (left + step) + "px";
break;
}
}
console.log("You pressed on: ", key);
});
Also, I recommend trying out jQuery, it makes these sorts of things much simpler. Especially for beginners it's easier to understand, but you should be careful not to forget the "vanilla" way to do it.
Related
I started to build a simple JavaScript game this morning, I'm trying to figure out how I can control so that the div "box" can't be permitted to move outside of it's parent container? My guess would be with an if statement controlling the offsetLeft and offsetTop?
Javascript here:
(function () {
"use strict";
var box = document.querySelector(".box");
document.addEventListener("keydown", function (event) {
var key = event.key;
var left = box.offsetLeft;
var top = box.offsetTop;
var step = 10;
switch (key) {
case "ArrowUp":
event.preventDefault();
box.style.top = top - step + "px";
break;
case "ArrowDown":
event.preventDefault();
box.style.top = top + step + "px";
break;
case "ArrowLeft":
event.preventDefault();
box.style.left = left - step + "px";
break;
case "ArrowRight":
event.preventDefault();
box.style.left = left + step + "px";
break;
}
console.log(event.key);
});
window.console.log("Sandbox is ready!");
})();
CSS here:
h1 {
text-align: center;
}
h3 {
color: green;
}
.content {
border: 1px solid black;
background-color: #eee;
padding: 2em;
margin: 0 auto;
height: 500px;
width: 800px;
border-radius: 30px;
text-align: center;
}
.box {
position: absolute;
height: 100px;
width: 100px;
background-color: green;
}
HTML below:
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style/style.css" />
</head>
<body>
<h1>Simple game</h1>
<div id="content" class="content">
<div class="box"></div>
</div>
<script src="js/main.js"></script>
</body>
</html>
CSS and HTML coded added.
Fiddle here:
https://jsfiddle.net/uwp0s9jz/
Please see the code below.
(function () {
"use strict";
var box = document.querySelector(".box");
var container = document.getElementById('content').getBoundingClientRect()
var paddingSize = 32
document.addEventListener("keydown", function (event) {
var key = event.key;
var left = box.offsetLeft;
var top = box.offsetTop;
var step = 10;
switch (key) {
case "ArrowUp":
event.preventDefault();
if (top > container.top + paddingSize) {
box.style.top = top - step + "px";
}
break;
case "ArrowDown":
event.preventDefault();
if (top < container.height - container.x - paddingSize) {
box.style.top = top + step + "px";
}
break;
case "ArrowLeft":
event.preventDefault();
if (left > container.left + paddingSize) {
box.style.left = left - step + "px";
}
break;
case "ArrowRight":
event.preventDefault();
if (left < container.width - container.y - paddingSize) {
box.style.left = left + step + "px";
}
break;
}
console.log(event.key);
});
})();
Fiddle here
You need to use getBoundingClientRect() to determine if you out of boundary I have updated the top and left for you as a start. You will need to factor in the border-radius if you want.
Fiddle updated: here
Use box parent offsets to determine the position of the box.
fiddle link
(function () {
"use strict";
var box = document.querySelector(".box");
var boxparent = document.querySelector(".content");
var temp;
document.addEventListener("keydown", function (event){
var key = event.key;
var left = box.offsetLeft;
var top = box.offsetTop;
var step = 10;
event.preventDefault();
switch (key) {
case "ArrowUp":
temp = top - step;
if(temp > boxparent.offsetTop)
box.style.top = temp + "px";
break;
case "ArrowDown":
temp = top + step;
if((temp + step + step) < boxparent.offsetHeight)
box.style.top = top + step + "px";
break;
case "ArrowLeft":
temp = left - step;
if(temp > boxparent.offsetLeft)
box.style.left = left - step + "px";
break;
case "ArrowRight":
temp = left - step;
if((left + box.offsetWidth) < boxparent.offsetWidth)
box.style.left = left + step + "px";
break;
}
});
})();
I made this code: https://code.sololearn.com/W3i7v2LuHhoB but I can't get the object collision to work. I searched on a lot of forums, YouTube, etc and still can't find it.
var rightArrow = 0;
function leftArrowPressed() {
var element = document.getElementById("image1");
element.style.left = parseInt(element.style.left) - 5 + 'px';
}
function rightArrowPressed() {
if (rightArrow === 0)
var element = document.getElementById("image1");
element.style.left = parseInt(element.style.left) + 5 + 'px';
}
function upArrowPressed() {
var element = document.getElementById("image1");
element.style.top = parseInt(element.style.top) - 5 + 'px';
}
function downArrowPressed() {
var element = document.getElementById("image1");
element.style.top = parseInt(element.style.top) + 5 + 'px';
}
function moveSelection(evt) {
switch (evt.keyCode) {
case 37:
leftArrowPressed();
break;
case 39:
rightArrowPressed();
break;
case 38:
upArrowPressed();
break;
case 40:
downArrowPressed();
break;
}
};
I don't get any errors.
I want to be able to move a div with the id cube using the keyboard arrows. Going left and right works correctly, but I can't make it go up and down.
var output=document.getElementById("output");
var cube=document.getElementById("cube");
var left=0;
var top=0;
document.addEventListener("keydown", function(e) {
output.innerHTML='Key code: ' + e.which + '<br />' + 'Key Name: ' + e.key;
var key=e.which;
switch (key) {
case 38: //arrow up
top = top - 10;
cube.style.top= top + "px";
cube.style.background="green";
break;
case 40: //arrow down
top = top + 10;
cube.style.top= top + "px";
cube.style.background="#14B4AA";
break;
case 39: //arrow right
left = left + 10;
cube.style.left= left + "px";
cube.style.background="blue";
break;
case 37: //arrow left
left = left - 10;
cube.style.left= left + "px";
cube.style.background="brown";
break;
}
});
...
You can't have a global variable named "top".
top is a host object, it points to the outermost window object and is most useful when used from within a frame
https://humanwhocodes.com/blog/2007/06/03/javascript-variable-names-you-shouldn-t-use/
Your code works correctly if the variable name is changed, or if it's scoped somewhere other than window (e.g. inside the event listener).
var output=document.getElementById("output");
var cube=document.getElementById("cube");
var left=0;
var t=0;
document.addEventListener("keydown", function(e) {
output.innerHTML='Key code: ' + e.which + '<br />' + 'Key Name: ' + e.key;
var key=e.which;
e.preventDefault(); // used to prevent window scroll on up/down keys
switch (key) {
case 38: //arrow up
t = t - 10;
cube.style.top= t + "px";
cube.style.background="green";
break;
case 40: //arrow down
t = t + 10;
cube.style.top= t + "px";
cube.style.background="#14B4AA";
break;
case 39: //arrow right
left = left + 10;
cube.style.left= left + "px";
cube.style.background="blue";
break;
case 37: //arrow left
left = left - 10;
cube.style.left= left + "px";
cube.style.background="brown";
break;
}
});
#cube {position: absolute}
<div id="cube">CUBE</div>
<div id="output">OUTPUT</div>
(note when running the above you have to click inside the snippet to get the key events to reach it)
You probably just missing position:absolute; for cube div.
See the Snippet below:
var output=document.getElementById("output");
var cube=document.getElementById("cube");
var left=0;
var topPx=0;
document.addEventListener("keydown", function(e) {
output.innerHTML='Key code: ' + e.which + '<br />' + 'Key Name: ' + e.key;
var key=e.which;
switch (key) {
case 38: //arrow up
topPx = topPx - 10;
cube.style.top= topPx + "px";
cube.style.background="green";
break;
case 40: //arrow down
topPx = topPx + 10;
cube.style.top= topPx + "px";
cube.style.background="#14B4AA";
break;
case 39: //arrow right
left = left + 10;
cube.style.left= left + "px";
cube.style.background="blue";
break;
case 37: //arrow left
left = left - 10;
cube.style.left= left + "px";
cube.style.background="brown";
break;
}
});
#cube{
width:100px;
height:100px;
background:red;
position:absolute;
}
#output{
float:right;
}
<div id="cube">
</div>
<div id="output">
</div>
You can test it here
First, your code does move the cube left and right, but only if you've initially set the cube up with position:absolute or position:relative. You can't move elements that are in the normal document flow unless you "free them" from that flow with position.
The next issue is that you are hard-coding top and left instead of setting them to values that represent the current location of the cube. You'll need to move them to be inside of your event handler, which will also change their scope and in the case of top (which is also a Global variable), this scope change will prevent naming collisions.
Also, instead of getting the values for top and left from the .style property, get them from the final computed style with getComputedStyle() because if your element doesn't have an inline style set for it to begin with, style.top and style.left will return undefined.
var output=document.getElementById("output");
var cube=document.getElementById("cube");
document.addEventListener("keydown", function(e) {
output.innerHTML='Key code: ' + e.which + '<br />' + 'Key Name: ' + e.key;
var key=e.which;
// You need to move the cube relative to where it currently is
// And, you should get the current style based on the final computed value, not the inline style
var left= parseInt(getComputedStyle(cube).left);
var top = parseInt(getComputedStyle(cube).top);
switch (key) {
case 38: //arrow up
top = top - 10;
cube.style.top= top + "px";
cube.style.background="green";
break;
case 40: //arrow down
top = top + 10;
cube.style.top= top + "px";
cube.style.background="#14B4AA";
break;
case 39: //arrow right
left = left + 10;
cube.style.left= left + "px";
cube.style.background="blue";
break;
case 37: //arrow left
left = left - 10;
cube.style.left= left + "px";
cube.style.background="brown";
break;
}
});
#cube { width:50px; height:50px; border:1px solid black; position:absolute; }
<div id="output"></div>
<div id="cube"></div>
I'm trying to make snake game in js and i have this movement code, where sq is moving DIV:
window.onkeyup = function move(e)
{
switch(e.keyCode)
{
case 37:
function moveLeft()
{
sq.style.left = parseInt(sq.style.left) - 20 + 'px';
checkGameOver();
}
setInterval(moveLeft, 500);
break;
case 38:
function moveUp()
{
sq.style.top = parseInt(sq.style.top) - 20 + 'px';
checkGameOver();
}
setInterval(moveUp, 500);
break;
case 39:
function moveRight()
{
sq.style.left = parseInt(sq.style.left) + 20 + 'px';
checkGameOver();
clearTimeout(timeLeft);
}
setInterval(moveRight, 500);
break;
case 40:
function moveDown()
{
sq.style.top = parseInt(sq.style.top) + 20 + 'px';
checkGameOver();
}
setInterval(moveDown, 500);
break;
}
}
But any time i change move direction, last direction stays and movement is not correct. The question is how can i make correct movement and also how to stop a div?
Assign the interval to a variable and clear it before setting a new interval:
var movementInterval;
window.onkeyup = function move(e)
{
if(movementInterval) {
clearInterval(movementInterval);
}
switch(e.keyCode)
{
case 37:
function moveLeft()
{
sq.style.left = parseInt(sq.style.left) - 20 + 'px';
checkGameOver();
}
movementInterval = setInterval(moveLeft, 500);
break;
case 38:
function moveUp()
{
sq.style.top = parseInt(sq.style.top) - 20 + 'px';
checkGameOver();
}
movementInterval = setInterval(moveUp, 500);
break;
case 39:
function moveRight()
{
sq.style.left = parseInt(sq.style.left) + 20 + 'px';
checkGameOver();
clearTimeout(timeLeft);
}
movementInterval = setInterval(moveRight, 500);
break;
case 40:
function moveDown()
{
sq.style.top = parseInt(sq.style.top) + 20 + 'px';
checkGameOver();
}
movementInterval = setInterval(moveDown, 500);
break;
}
}
Otherwise you will just keep on creating new intervals with each keypress.
this does not move the box when pressing the right and left arrow.
please post in the comments if you can help.
window.addEventListener("keydown", testkey , false );
var el = document.getElementById("player");
//changes the x position by a value
function changex(num) {
el.style.left = ((num + el.style.left) + "px");
}
//changes the y position by a value
function changey(num2) {
el.style.top = ((num2 + el.style.top) + "px");
}
//sets x and y position of box
function setpos(x, y) {
el.style.left = (x + "px");
el.style.top = (y + "px");
}
//this returns the key that is pressed
function testkey(e) {
if (e.keyCode == "37") {
//left key
changex(-10);
}
else if (e.keyCode == "39") {
//right key
changex(10);
}
}
setpos(0,0);
I see two issues:
First
You are adding numeric values to strings, which results in concatination. For example:
((num + el.style.left) + "px") is equivalent to 10 + 0px + px, which results in a string like 100pxpx. This is not a valid CSS value.
I suggest using parseInt to convert existing style values from strings to numbers:
el.style.left = parseInt(el.style.left) + num + "px";
For further reference, see Get a number for a style value WITHOUT the “px;” suffix.
Second
You'll need to position the element before you can use left,right,top, or bottom CSS definitions. The MDN notes that left (for example) only applies to "positioned elements".
Below, I've used position:absolute, but any valid position value will work.
For further reference, see css “left” not working.
Working Example
window.addEventListener("keydown", testkey, false);
var el = document.getElementById("player");
function changex(num) {
el.style.left = parseInt(el.style.left) + num + "px";
}
function changey(num) {
el.style.top = parseInt(el.style.top) + num + "px";
}
function setpos(x, y) {
el.style.left = (x + "px");
el.style.top = (y + "px");
}
function testkey(e) {
switch (e.keyCode) {
case 37: changex(-10); break;
case 38: changey(-10); break;
case 39: changex(10); break;
case 40: changey(10); break;
default:
}
}
setpos(0, 0);
#player {
position: absolute;
}
<div id="player">test</div>
in your changex() and changey() functions, you're trying to do calculations between a number and a string. num comes in as a number but el.style.left is the string '0px'. put parseInt() around el.style.left like this and it works:
el.style.left = ((num + parseInt(el.style.left)) + "px");
Also make sure your player element has position:absolute applied via CSS.