keycodes not working in javascript - 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.

Related

Move div upwards and downwards using keyboard arrows

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>

Shifting a div to the left on click in angularjs

So I am trying to allow the user to shift a div to the left or right in angularjs. Right now I have the function below. It works on the first click but all it does is toggle every click and is saying left is NaN. What am I doing wrong here? Also if someone has a better solution for this please let me know.
vm.scrollSelector = function(e, direction) {
var target = document.getElementById('item-selector');
var left = target.style.left;
if(direction === 'left') {
left += 600;
target.setAttribute('style', 'left: ' + left + 'px');
} else {
left -= 600;
target.setAttribute('style', 'left: ' + left + 'px');
}
}
So I quickly found the answer just by looking at the docs. Left is returned as a string so all I had to to was do parseInt(left) + 600 and it worked.
vm.scrollSelector = function(e, direction) {
var target = document.getElementById('item-selector');
var left = target.style.left.match(/\d+/);
left = parseInt(left[0], 10)
if(direction === 'left') {
left += 600;
target.setAttribute('style', 'left: ' + left + 'px');
} else {
left -= 600;
target.setAttribute('style', 'left: ' + left + 'px');
}
}
First try to see what value target.style.left is returning. It might be returning value like '10px'. You need to convert this into a number first then perform the addition or subtraction.

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.

Move an element with arrow keys

function docReady()
{
image = document.getElementById("someImage");
window.addEventListener("keydown", moveImage);
}
function moveImage(e)
{
if (e.keyCode == 37)
image.style.left = parseInt(image.style.left) - 5 + 'px';
if (e.keyCode == 38)
image.style.top = parseInt(image.style.top) - 5 + 'px';
if (e.keyCode == 39)
image.style.left = parseInt(image.style.left) + 5 + 'px';
if (e.keyCode == 40)
image.style.top = parseInt(image.style.top) + 5 + 'px';
console.log(image.style.left + ', ' + image.style.top);
}
So the code above is supposed to move an image around. However, it doesn't. The console returns blanks for image.style.left and image.style.top. Could you help me with fixing it?
P.S. If you would be so kind, can you also make it so that if the image is on the screen borders it will stop moving? Thank you so much!
You are missing some steps indeed.
To be precise, you should:
create the variable image outside the function (i.e., declare it global)
set the initial values of top, left
set the position of your element to absolute. Default is static and it doesn't support moving/styling with top/left/right/bottom.
call the whole thing on page load
And here's what you get once you follow the above steps:
window.onload = docReady;
var image;
function docReady() {
image = document.getElementById("someImage");
window.addEventListener("keydown", moveImage);
image.style.left = 0;
image.style.top = 0;
}
function moveImage(e) {
if (e.keyCode == 37)
image.style.left = parseInt(image.style.left) - 5 + 'px';
if (e.keyCode == 38)
image.style.top = parseInt(image.style.top) - 5 + 'px';
if (e.keyCode == 39)
image.style.left = parseInt(image.style.left) + 5 + 'px';
if (e.keyCode == 40)
image.style.top = parseInt(image.style.top) + 5 + 'px';
console.log(image.style.left + ', ' + image.style.top);
}
#someImage{
position:absolute;
}
<div id = "someImage"> not an image but a test </div>
(For the simplicity I'm using a plain text element instead of image, but that doesn't matter)

Calculating positioning of the parent Div

Hi i want to calculate the position of the Div. Pardon me if i am not able to explain it properly but i will try to explain everything in the simplest way. I am creating sidepanel ad and to place the panels i want the position of the width. When i upload the script on my server then i get a small script which we place on the publisher website and where our script runs inside the iframe. I want to get the position of the div which has a class 'content'. Here is the screen shot.
in the above screenshot the yellow highlighted script is calculating the position of the div class="content" which is in red box. My code was working fine but on the publisher site it was not working fine and i was only able to get only two Divs whose id is like ebDiv..... (these divs are above the yellow highlighted js).
Then i found out to read the parentDiv in order to get the content positions.
i wrote this code.
var parentDoc = window;
while (parentDoc !== parentDoc.parent) {
parentDoc = parentDoc.parent;
}
parentDoc = parentDoc.document;
var parentDiv = parentDoc.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < parentDiv.length; i++) {
if (parentDiv[i].className == "content") {
alert(parentDiv[i].offsetWidth);
alert(parentDiv[i].offsetLeft);
}
The width is calcuated as 1010 which is fine but i am just missing left positioning which i am getting using parentDiv[i].offsetLeft is 2.
Above the screenshot has width 1010 which is fine but left positioning is not correct.
i had this code to calculate the width.
function ReadDivPos(selector) {
var _divPos = "";
$(selector).each(function() {
var p = $(this).offset();
var w = $(this).width();
console.log("Top " + p.top) //top
console.log("left " + p.left) //left
console.log("right " + p.left + w) //right
console.log("offsetWidth " + w); //width
_divPos += "Left " + p.left + ",Width " + w + ",Avail Width " + window.screen.availWidth + ",Right " + (p.left + w) + "\\n";
});
return _divPos;
}
console.log(ReadDivPos(".content"));
when i am using the same code to calculate the positioning then it is not working .
var parentDoc = window;
while (parentDoc !== parentDoc.parent) {
parentDoc = parentDoc.parent;
}
parentDoc = parentDoc.document;
var parentDiv = parentDoc.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < parentDiv.length; i++) {
if (parentDiv[i].className == "content") {
$(parentDiv[i]).each(function() {
var p = $(this).offset();
var w = $(this).width();
console.log("Top " + p.top) //top
console.log("left " + p.left) //left
console.log("right " + p.left + w) //right
console.log("offsetWidth " + w); //width
_divPos += "Left " + p.left + ",Width " + w + ",Avail Width " + window.screen.availWidth + ",Right " + (p.left + w) + "\\n";
}
}
Can someone me explain me how to fix this. Jquery/Javascript anythingwould be fine. I am not good in the frontend things so i am sorry if i could not explain it better. Thanks in advance
Here is a function used to get the position on the page of an element:
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
while (element) {
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
Used like this:
var pos = getPosition(element);
var x = pos["x"];
var y = pos["y"];
I'm not sure if this is exactly what you need, but if not maybe you can tweak it to fit your situation

Categories