So if i had an element like this on HTML
index.html
<div><img id="2" src="1.jpg"><img id="2" src="2.jpg"></div>
that created by js like this
index.js
let image = document.createElement("img")
image.src = img.image
image.style.width = "725"
image.style.height = "1024"
image.setAttribute("id",img.index)
how can I make if the right arrow pressed it go to the top of the next image index
I've try this
image.onkeydown = function(e) {
e = e || window.event;
if (e.keyCode == '37') {
document.location.href = `#${img.index--}`
} else if (e.keyCode == '39') {
document.location.href = `#${img.index++}`
}
}
but didn't work
You should not change the document.location, the script will have to rerun because the page is reloaded. Instead just scrollIntoview:
Also no need for index, you can calculate the index from the content
const imageArr = [
"https://via.placeholder.com/725x1024/000000/FFFFFF/?text=image1",
"https://via.placeholder.com/725x1024/FF0000/0000FF/?text=image2",
"https://via.placeholder.com/725x1024/FFAAFF/00AA00/?text=image3"
]
const container = document.getElementById("imageContainer");
container.innerHTML = imageArr.map(img => `<img src="${img}" />`)
const images = container.querySelectorAll("img");
let current = 0;
const max = imageArr.length
window.addEventListener("keydown", function(event) {
if (event.defaultPrevented) {
return; // Do nothing if event already handled
}
const key = event.code;
if (key === "ArrowLeft") current--;
else if (key === "ArrowRight") current++
// wrap
if (current < 0) current = max; // change to current=0 if no wrap
else if (current >= max) current = 0; // change to current = max if no wrap
images[current].scrollIntoView()
})
<div id="imageContainer"></div>
I am new to JavaScript and this community. I apologize if this has been asked before, but the threads I found for this topic did not really help me with this specific problem.
I would like to achieve the following working:
Image 1 is displayed.
If you press the left arrow key (keydown) the image should change to image 2.
If you stop pressing (keyup), it should change to image 3.
If you press the right arrow key it should change to image 4 and on keyup, change to image 5.
The code is:
<img src="img/image1.png" id="myIMG">
and
var imgs = ["img/image5.png", "img/image3.png", "img/image1.png", "img/image4.png"];
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[imgs.indexOf(img.src) + (dir || 1)] || imgs[dir ? imgs.length - 1 : 0];
}
var keys = {};
$(document).keydown(function (event) {
keys[event.which] = true;
}).keyup(function (event) {
if(e.keyCode == 37){
delete keys[37];
changeIMG(+1);
}
else if(e.keyCode == 39){
delete keys[39];
changeIMG(+2);
}
});
function IMGLoop() {
if (keys[37]) {
changeIMG(+3);
} else if (keys[39]) {
changeIMG(+4);
}
setTimeout(IMGLoop, 20);
}
IMGLoop();
The issue is described below.
The keyup does not do anything and the keydown only works once and then I can not even switch between left and right anymore.
I need to do this with a loop because I also want to do other things on the loop that are not displayed in this code. I would appreciate any type of help.
Hope this helps you
var imgs = [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQgz2HMpGysZL6ifYfhqWASDoA0b2MyX-gyMuQszgYRv87yr9qug",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQV3JL_HtVvlLr3Xy-KQV5MNmIF2-kCb9cHB4oXkUKQ1jiLT0H",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRgDmo-5YpwYK9Yc35CK1oq3Y2zHDnXlu3q6m7GnSvLarDTRl0B",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQt2dZklq8eDbsNL1vZ0MTwZsm0KWDIxl6YifmbUqjPiE5lOmIe"
];
var showImageName = 2;
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[dir];
img.alt = dir;
}
var keyPressed = false;
function f(e) {
if (e.keyCode == 37) {
showImageName--;
if (showImageName == -1) {
showImageName = imgs.length - 1;
}
changeIMG(showImageName);
} else if (e.keyCode == 39) {
showImageName++;
if (showImageName == imgs.length) {
showImageName = 0;
}
changeIMG(showImageName);
}
}
$(document)
.keydown(function(e) {
if (!keyPressed) {
keyPressed = true;
f(e);
}
})
.keyup(function(e) {
if (keyPressed) {
keyPressed = false;
f(e);
}
});
changeIMG(0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img alt='' src="" id="myIMG">
Update after question edited
var imgs = [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQgz2HMpGysZL6ifYfhqWASDoA0b2MyX-gyMuQszgYRv87yr9qug",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQV3JL_HtVvlLr3Xy-KQV5MNmIF2-kCb9cHB4oXkUKQ1jiLT0H",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRgDmo-5YpwYK9Yc35CK1oq3Y2zHDnXlu3q6m7GnSvLarDTRl0B",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQt2dZklq8eDbsNL1vZ0MTwZsm0KWDIxl6YifmbUqjPiE5lOmIe",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnDWTv5oLaNgUm_SXQFSzzBJl-21c7wLCC6Hgld-ndQ1k0knly"
];
var showImageName = 2;
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[dir];
img.alt = dir;
}
var keyPressed = false;
function f(e, str) {
switch (str) {
case "up":
if (e.keyCode == 37) {
changeIMG(2);
} else if (e.keyCode == 39) {
changeIMG(4);
}
break;
case "down":
if (e.keyCode == 37) {
changeIMG(1);
} else if (e.keyCode == 39) {
changeIMG(3);
}
break;
}
}
$(document)
.keydown(function(e) {
if (!keyPressed) {
keyPressed = true;
f(e, "down");
}
})
.keyup(function(e) {
if (keyPressed) {
keyPressed = false;
f(e, "up");
}
});
changeIMG(0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img alt='' src="" id="myIMG">
I am making a classic snake remake in JavaScript just for weekend fun, and I ran into this problem that if I press buttons quite fast - the snake (caterpillar in my case) is able to change direction to opposite and run into itself.
The way to recreate this situation is as follows:
direction is for example 'left'
press up(or down) and press right quickly after
now the caterpillar goes backwards. And my goal is it should make U-turn
I made the checks for opposite dir, but this doesn't prevent this
update = function() {
if (cat.direction != 'right' && key[37] === true) {
cat.direction = 'left';
}
if (cat.direction != 'left' && key[39] === true) {
cat.direction = 'right';
}
if (cat.direction != 'down' && key[38] === true) {
cat.direction = 'up';
}
if (cat.direction != 'up' && key[40] === true) {
cat.direction = 'down';
}
};
the full code
I was using normal addEventListener for the key listening, but I changed it for another approach (found somewhere), where I do update on keys very often and caterpillar moving is happening only from time to time, as I thought it might be a problem to directly associate drawing, changing direction and moving in the same time interval. I hope I am understandable, sorry if something isn't clear - I would be happy to provide more info if so.
One solution is to not process more than one key per move, but to allow more responsiveness you could implement a key buffer, instead of maintaining the key states as you do know. You would only collect arrow key presses in that buffer, and not push any repetitions of the same key into it.
Here are the relevant changes to the code:
Initialise the key buffer:
var keyBuffer = [];
Push arrow keys into the buffer when pressed:
var keyDown = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
// *** Queue the arrow key presses
if (keyCode >= 37 && keyCode <= 40 &&
keyCode !== keyBuffer[keyBuffer.length-1] && ) {
keyBuffer.push(keyCode);
}
};
Process one key from the buffer at a time:
var update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};
Only process next key when about to move:
function loop() {
board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();
counter += 5*cat.multiplier;
};
That's it. See fiddle below:
var canvas = document.getElementById("board");
var context = canvas.getContext("2d", {alpha:false});
var pieceSideLength = canvas.width / 40;
var key = [];
var keyBuffer = [];
window.addEventListener('keyup', function(e) {
this.keyUp.call(this, e);
}, false);
window.addEventListener('keydown', function(e) {
this.keyDown.call(this, e);
}, false);
function Piece(x,y){
this.x = x;
this.y = y;
}
board = {
leftBound: 0,
rightBound: canvas.width / pieceSideLength,
topBound: 0,
bottomBound: canvas.height / pieceSideLength,
drawPiece: function(x, y, color){
context.fillStyle = color;
context.fillRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
context.strokeStyle = 'white';
context.strokeRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
},
resetCanvas: function(){
context.clearRect(0,0,canvas.width,canvas.height);
}
};
//cat as for caterpillar
cat = {
x: canvas.width/pieceSideLength/2, //initial x
y: canvas.height/pieceSideLength/2, //initial y
pieces: [],
direction: 'up',
color: '#5da03c',
shouldGrow: false,
multiplier: 5,
init: function(){
cat.pieces.push(new Piece(this.x, this.y));
},
move: function(){
if(cat.pieces.length <= 10){
cat.shouldGrow = true;
}
var newX = cat.pieces[cat.pieces.length-1].x;
var newY = cat.pieces[cat.pieces.length-1].y;
if(cat.direction=='up'){
cat.makeNewHeadAt(newX,newY-1);
}
if(cat.direction=='down'){
cat.makeNewHeadAt(newX,newY+1);
}
if(cat.direction=='left'){
cat.makeNewHeadAt(newX-1,newY);
}
if(cat.direction=='right'){
cat.makeNewHeadAt(newX+1,newY);
}
cat.grow();
},
makeNewHeadAt: function(x,y){
cat.pieces.push(new Piece(x,y));
},
grow: function(){
if(cat.shouldGrow == false){
cat.pieces.shift();
} else {
cat.shouldGrow = false;
}
},
draw: function(){
for(i=0;i<cat.pieces.length;i++){
var p = cat.pieces[i];
board.drawPiece(p.x,p.y,cat.color);
}
}
};
cat.init();
update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};
keyUp = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
this.key[keyCode] = false;
};
keyDown = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
// *** Queue the key presses
if (keyCode >= 37 && keyCode <= 40 &&
keyCode !== keyBuffer[keyBuffer.length-1]) {
keyBuffer.push(keyCode);
}
this.key[keyCode] = true;
};
var counter = 0;
function loop() {
board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();
counter += 5*cat.multiplier;
};
setInterval(loop, 1);
body { margin: 0px }
<div>
<canvas id="board" width="300" height="200" style="display: block; margin: 0 auto; background-color: #553300; border-style: solid; border-color: green;"></canvas>
</div>
Limiting the buffer size
You can limit the buffer size by replacing this:
keyBuffer.push(keyCode);
with:
keyBuffer = keyBuffer.slice(-2).concat(keyCode);
This will limit the size to 3. Adjust the slice argument as desired.
You can keep track of whether the snake has 'moved'. If you receive keyboard input, don't react to another keypress until the snake has moved. This way you're only allowing 1 key for each movement, so you can't change direction and run into yourself.
Modified example: link
update = function() {
if (moved = true) {
if(cat.direction != 'right' && key[37] === true){
and so forth
Was wondering if you could help me. I have several inputs on a page with multiple tabs.I would like left + right arrows to change tab but ONLY if no inputs on the page are in focus
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (NO_INPUTS_IN_FOCUS) {
if (e.keyCode == '37') {
// left arrow
}
else if (e.keyCode == '39') {
// right arrow
}
}
}
Any help appreciated, Thanks.
For your case :
if (!($("input").is(":focus"))) {
NO_INPUTS_IN_FOCUS = true;
}
else {
NO_INPUTS_IN_FOCUS = false;
}
Try
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
var target = e.target || e.srcElement,
tag = target.tagName.toLowerCase();
if (tag != "input" && tag.indexOf("select") ==-1 && tag != "textarea") {
if (e.keyCode == '37') {
// left arrow
}
else if (e.keyCode == '39') {
// right arrow
}
}
}
I'm pretty new when it comes to getting my head around JS functions. Everything I've used before, I've tended to use as-is, but I've been trying to combine and modify a function to get a Div to toggle (height & opacity) on a specific keypress. I have the first part (can get the div to show on a 'ctrl + o' combo), but can't combine it with an if statement to show or hide, based on current display status.
Current working 'show only' JS:
$(document).keydown(function (e) {
if (e.keyCode == 79 && e.ctrlKey) {
document.getElementById('thediv').style.height = 'auto';
document.getElementById('thediv').style.opacity = '1';
return false;
}
});
Not working 'toggle on/off' JS (I've tried changing this all over the place; this is more to give an idea of what I'm trying to achieve):
$(document).keydown(function (e) {
if (e.keyCode == 76 && e.ctrlKey) {
function toggler('thediv') {
var myDiv = document.getElementById('thediv').style.height;
if (myDiv == "auto") {
document.getElementById('thediv').style.height = "0px";
document.getElementById('thediv').style.opacity = "0";
} else {
document.getElementById('thediv').style.height = "auto";
document.getElementById('thediv').style.height = "1";
}
}
}
});
Any help would be really appreciated!
You want to show and hide an element, why set its height and visibility? Just show/hide it with toggle.
$(document).keydown(function (e) {
if (e.keyCode == 76 && e.ctrlKey) {
$("#thediv").toggle();
}
});
Looking at your code
$(document).keydown(function (e) {
if (e.keyCode == 76 && e.ctrlKey) {
//This funciton is never called, you define it, do not call it!
function toggler('thediv') { //<-- Error Here, you have a string as an argument?
var myDiv = document.getElementById('thediv').style.height;
if (myDiv == "auto") {
document.getElementById('thediv').style.height = "0px"; //<--Bad practice using document.getElementById('thediv') over and over. Store it into a variable and reference it.
document.getElementById('thediv').style.opacity = "0";
} else {
document.getElementById('thediv').style.height = "auto";
document.getElementById('thediv').style.height = "1";
}
}
}
});