Move div upwards and downwards using keyboard arrows - javascript

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>

Related

Is there a way to call a function by a key press in Javascript?

Is there a way to call a function on the event of a key press.
My goal is to make a movable block and I was wondering if you could call the function to move a <div> block around. I also have an issue with making the character visible so it would be helpful to help me with that!
JavaScript
//variables
var player = document.getElementById('player');
var character = {
left: player.style.left + 1,
right: player.style.right + 1,
top: player.style.top + 1,
bottom: player.style.bottom + 1,
body: document.createElement('div'),
}
//functions
function running() {
console.log("Running");
console.log("Program running");
document.appendChild('div');
}
function loop() {
running();
}
function moveRight() {
character.style.position = absolute;
character.style.top = top + "px";
character.style.right = right + 2 + "px";
}
function moveLeft() {
character.style.position = absolute;
character.style.top = top + "px";
character.style.left = left + 2 + "px";
}
function moveup() {
character.style.position = absolute;
character.style.top = top + "px";
character.style.right = right + 2 + "px";
}
//functions called
loop();
HTML
<!DOCTYPE html>
<html>
<head>
<title>RPG</title>
</head>
<body>
<div id="allCode">
<script type="text/javascript" src="index.js"></script>
<style type="text/css" src="style.css"></style>
</div>
<div id="player"></div>
</body>
</html>
There are a lot of examples on how to deal with key handling events in javascript, this should get you started :
document.addEventListener('keydown', function(event) {
switch (event.keyCode) {
case 37:
//left function
break;
case 38:
//Up function
break;
case 39:
//Right function
break;
}
});
Edit: The .keyCode, .which, .charCode are deprecated properties:
so you should use event.key
for example:
window.addEventListener("keydown", function (event) {
if (event.defaultPrevented) {
return; // Do nothing if the event was already processed
}
switch (event.key) {
case "Up": // IE/Edge specific value
case "ArrowUp":
//Up function
break;
case "Left": // IE/Edge specific
case "ArrowLeft":
//left function
break;
case "Right": // IE/Edge specific
case "ArrowRight":
//Right function
break;
default:
return; // No key event
}
event.preventDefault(); // Avoid key handling twice
}, true);
Maybe this can lead you in the right direction. It's a link to move an object using arrow keys.
https://www.includehelp.com/code-snippets/move-object-with-arrow-keys-using-javascript-function.aspx

JavaScript game - How to control a children div from not moving outside of it's parent container

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;
}
});
})();

Moving all elements with class ".something" in plain javascriot

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.

Javascript moving div to new position with arrow keys

I want to make a div able to move with arrow keys in 4 direction with multikey support(e.x. moving to top left) onkeypress. When i click some of the arrows i expect moving to that direction until i put my finger up from that button. Although the move is just once which i don't understand why is happening.
function place(id,x_pos, y_pos) {
var element = document.getElementById(id);
element.style.position = "absolute";
element.style.left = x_pos+'px';
element.style.top = y_pos+'px';
}
setInterval(update,1);
function update(){
document.addEventListener('keydown', keyPress);
}
function keyPress(e) {
var x = e.keyCode;
switch (x) {
case 37:
place('move', move.style.left-10, move.style.top);
break;
case 39:
place('move', move.style.left+10, move.style.top);
break;
case 38:
place('move', move.style.left, move.style.top-10);
break;
case 40:
place('move', move.style.left, move.style.top+10);
break;
}
// console.log(x);
}
*{
margin:0;
padding:0;
}
div#move{
background-color:yellow;
width:5vw;
height:5vw;
}
<div id='move'></div>
The problem with your code is that element.style.left give result as 10px and when you add 10 on 10px it will be a string like 10px10 which will make the property value incorrect.Since the first time the property is not set so first assignment id working fine. You need to get the left and right in numerical.
You also do not need to bind the update function with document with setInterval. Once is enough.
Check the code below
function place(id,x_pos, y_pos) {
var element = document.getElementById(id);
element.style.position = "absolute";
element.style.left = x_pos+'px';
element.style.top = y_pos+'px';
}
function update(){
document.addEventListener('keydown', keyPress);
}
function keyPress(e) {
var x = e.keyCode;
var move = document.getElementById("move").getBoundingClientRect();
var left = parseInt(move.left,10);
var top = parseInt(move.top,10)
switch (x) {
case 37:
place('move', left -10, top);
break;
case 39:
place('move', left+10, top);
break;
case 38:
place('move', left, top-10);
break;
case 40:
place('move', left, top+10);
break;
}
// console.log(x);
}
update();
*{
margin:0;
padding:0;
}
div#move{
background-color:yellow;
width:5vw;
height:5vw;
}
<div id='move'></div>
const move=document.getElementById('move');
var moveLeft = 0;
function direction(e){
if(e.keyCode==39){
moveLeft +=2;
move.style.left = moveLeft + 'px';
if(moveLeft>=600){
moveLeft -=2;
}
}
if(e.keyCode==37){
moveLeft -=2;
move.style.left = moveLeft + 'px';
}
if(e.keyCode==38){
moveLeft -=2;
move.style.top = moveLeft + 'px';
if(moveLeft>=600){
moveLeft +=2;
}
}
if(e.keyCode==40){
moveLeft +=2;
move.style.top = moveLeft + 'px';
}
}
document.onkeydown = direction;
#move{
position: absolute;
height: 50px;
width: 50px;
background-color: yellow
}
<div id="move"></div>
You don't need setInterval. Just register your listener, and it will handle every keypress.
document.addEventListener('keydown', keyPress);
function keyPress(e) {
var x = e.keyCode;
switch (x) {
case 37:
place('move', move.style.left-10, move.style.top);
break;
case 39:
place('move', move.style.left+10, move.style.top);
break;
case 38:
place('move', move.style.left, move.style.top-10);
break;
case 40:
place('move', move.style.left, move.style.top+10);
break;
}
// console.log(x);
}

keycodes not working in javascript

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.

Categories