Ignoring delay when a key is held down? - javascript

Checked out other posts, no help...
I'm using asdw to move an object around within a limited space. I'm trying to figure out how to allow the object to move around while the key is pressed, without the momentary delay at the beginning.
Thanks...
$(document).ready(function(){
var longitude = 0;
var latitude = 0;
$('body#sense').keypress(function(){
if(event.which == 65 || event.which == 97){
// Left
if(longitude != 0){
longitude = longitude + 10;
$('img#map').css('margin-left', longitude);
}
}
else (event.which == 68 || event.which == 100){
// Right
if(longitude > -200){
longitude = longitude - 10;
$('img#map').css('margin-left', longitude);
}
}
});
});
The web page
<body id="sense">
<h2><center>Use your 'asdw' keys to move the map around</center></h2>
<div id="box">
<img id="map" src="http://www.toronto.ca/culture/victoria-square/images/ch0/Victoria-Square-map-t.gif" alt="" />
</div>
</body>
The holding the image has a set width and height, both smaller than the image. The is set to overflow:hidden, so the javascript moves the image around within the div so different parts are visible.
The CSS
div#box {
margin:0px auto;
width:225px;
height:225px;
overflow:hidden;
}
div#box img {
}

Use the keyDown event and then start your own timer interval to control your own repeat interval (ignore the system repeat interval) and then cancel the timer on keyUp. Ignore the other key events. You can pick your own repeat time in the setInterval calls.
var timer = null;
function increaseLongitude() {
// your code here
}
function decreaseLongitude() {
// your code here
}
$("#sense").keyDown(function(e) {
if (!timer) {
if (e.which == 65 || e.which == 97) {
timer = setInterval(increaseLongitude, 100);
increaseLongitude();
} else if (e.which == 68 || e.which == 100) {
timer = setInterval(decreaseLongitude, 100);
decreaseLongitude();
}
}
});
$("#sense").keyUp(function(e) {
if (timer) {
clearInterval(timer);
timer = null;
}
});

Try using the keydown event instead

Checkout this version of your code. it can be done with 'keydown' event. I believe this is the ideal way it should be done.
http://jsfiddle.net/valllabh/yFxDN/10/

Related

Using jQuery to snap to div on scroll

I have built a simple vertical scrollable website that snaps the view to divs when the user scrolls up or down the page. You cans see a demo here: http://dev.driz.co.uk/snap.html
The JS is fairly simple:
var currentScreen = 0;
var scrollReady = false;
var screens = new Array( 'one',
'two',
'three');
function scrollNext() {
if( currentScreen < screens.length-1 && scrollReady == true ) {
currentScreen++;
performScroll();
}
}
function scrollPrev() {
if( currentScreen > 0 && scrollReady == true ) {
currentScreen--;
performScroll();
}
}
function performScroll() {
scrollReady = false;
var newYPos = Math.ceil($('#'+screens[currentScreen]).offset().top);
$('.snap').animate({scrollTop: newYPos }, 500, function() { scrollReady = true; });
}
$(document).ready(function() {
scrollReady = true;
$('.snap').bind('mousewheel', function (event, aS, aQ, deltaY) {
event.preventDefault();
if (deltaY > 0) {
scrollPrev();
} else {
if (deltaY < 0) {
scrollNext();
}
}
return false;
});
$(document).bind('keyup', function (event) {
if (event.keyCode == 40 || event.keyCode == 38) {
event.preventDefault();
if (event.keyCode == 40) {
if (scrollReady == true) {
scrollNext();
}
} else {
if (event.keyCode == 38) {
if (scrollReady == true) {
scrollPrev();
}
}
}
}
});
$(document).bind('keydown', function (event) {
if (event.keyCode == 40 || event.keyCode == 38 ) {
event.preventDefault();
}
});
});
However I can only scroll to the first two divs and can't get to the third one... Any ideas why this is happening? I can't see issues that would cause this that wouldn't effect the first two from working...
Update: Sometimes you can get it to scroll to the third div (scrolling up and down until it does), but it skips the second div and then when the user scrolls up again, it jumps all the way to the top... so something weird is happening.
Update 2: I've noticed that currentScreen is incorrectly 2 when you scroll to the second div which is why you can't scroll to the third div. Any ideas why though?
Update 3: It seems that the scrollReady variable isn't preventing the functions from being called multiple times in places, as if you scroll up and down a few times, you find that sections are scrolled passed multiple times. Which shouldn't happen, you should only be able to scroll up one and down one at a time.
Store the values of section offsets in variable and then try, it will work.
check this on codepen.
http://codepen.io/sandeshdamkondwar/pen/veGko?editors=100
In scrollNext() function Your conditional checking is wrong
on second screen this condition will be false and therefore it is not moving to third screen.
It should be
currentScreen < screens.length

How to show element when a key is pressed, then if it is pressed again, hide the element?

I have this project where I have a side menu which can be toggled using [Ctrl] + [Z]. I want it to hide the very next time the [Ctrl] + [Z] pattern is pressed. My mediocre knowledge of JavaScript hinders me being able to phrase it using google, so I ultimately didn't find anything, so I'm coming here. With the amount of JavaScript I know this technically should work, but logically wouldn't work. Any ideas? Here's my code:
var letter = {
z: 90
...
};
$(document).ready(function() {
$("body").keydown(function(event) {
// toggles element the first time
if(event.ctrlKey && event.which === letter.z) {
$("[data-location='top']").slideDown("fast");
$("[data-location='bottom']").slideDown("fast");
}
// hides element the second time
if(event.ctrlKey && event.which === letter.z) {
$("[data-location='top']").slideUp("fast");
$("[data-location='bottom']").slideUp("fast");
}
});
});
Any help would be very much appreciated! :-)
The .slideToggle() function is what you're looking for.
var letter = {
z: 90
...
};
$(document).ready(function() {
$("body").keydown(function(event) {
if(event.ctrlKey && event.which === letter.z) {
$("[data-location='top']").slideToggle("fast");
$("[data-location='bottom']").slideToggle("fast");
}
});
});
JavaScript:
var letter = {
z: 90
};
$(document).ready(function() {
var visible = false;
$("body").keydown(function(event) {
// toggles element the first time
if(!visible && event.ctrlKey && event.which === letter.z) {
visible = true;
$("[data-location='top']").slideDown("fast");
$("[data-location='bottom']").slideDown("fast");
} else if(visible && event.ctrlKey && event.which === letter.z) {
visible = false;
$("[data-location='top']").slideUp("fast");
$("[data-location='bottom']").slideUp("fast");
}
});
});​
HTML:
<div id="top" class="hidden" data-location="top"></div>
<div id="bottom" class="hidden" data-location="bottom"></div>​
CSS:
#top {height:100px;width:500px;background-color:red;}
#bottom {height:100px;width:500px;background-color:blue;}
.hidden {display:none;}
Fiddle
You only need to bind once to keydown, and then thrw your logic in there. So you code will become:
var letter = {
z: 90
...
};
$(document).ready(function() {
$("body").keydown(function(event) {
// toggles element the first time
if(event.ctrlKey && event.which === letter.z) {
$("[data-location='top']").toggle("fast");
$("[data-location='bottom']").toggle("fast");
}
});
});

Continuous movement when a key is held down

Is it possible in jQuery to have an element continuously move when the key is held down?
I've tried a few ways but they always have a break in between animation calls. The code I currently have:
$(document).keydown(function (e) {
if (e.which == 37) {
$('#you').stop().animate({
left: '-=16px'
}, 10);
}
});
$(document).keyup(function (e) {
$('#you').stop();
});
.animate() isn't always the best way.
// cache jQuery objects for performance
var you = $( "#you" )
, doc = $( document )
// variable to hold motion state
, activeMotion
// goDown motion, adjust numbers to taste
, goDown = function(){
you.css( "left" , you.css( "left" ) - 16 );
if ( activeMotion === goDown ) {
setTimeout( goDown , 10 );
}
}
doc.keydown( function( e ) {
if ( e.which === 37 && activeMotion !== goDown ) {
activeMotion = goDown;
goDown();
}
// all directions can go here in seperate if/else statements
// be sure to include "activeMotion !== goDown" else every time
// keydown event fires, it will start a new goDown loop.
} );
doc.keyup( function () {
// simply ends any motion that checked activeMotion
activeMotion = null;
} );
Instead of animating the element, rather just move it by some amount of pixels. 16 will probably be too much because it will go too fast.
I think you are seeing the break between animation calls because of your timing.
If you look at your operating systems keyboard repeat time interval, it should be around 35 milliseconds - test it here.
On top of that you are animating every 10ms, not counting the time it takes to run all the animation functions, etc. So why not simplify the animation and not worry about time intervals (try this demo):
var block = $('.block'),
leftPos;
$(document).keydown(function (e) {
leftPos = block.position().left;
leftPos += (e.which == 37) ? -5 : 0;
leftPos += (e.which == 39) ? 5 : 0;
block.css('left', leftPos);
});

Different actions on multiple Keydown event

Okay, so my question (im hoping) is fairly simple. I want to know what to do so that I can create different events for the same keycode. For instance Id like to fade out a div and fade a new one in on the first keypress, then fade that one out and fade a new one in on keypress.
Thanks!
$(document).keydown(function() {
if (event.keyCode == '40') {
$('.div-1').fadeOut("slow")
$('.div-2').fadeIn("slow")
// I'd like this event to occur on the Second keydown
$('.div-2').fadeOut("slow")
$('.div-3').fadeIn("slow")
}
});
try
var hits = 0;
$(document).keydown(function() {
if (event.keyCode == '40') {
hits++;
if (hits % 2 == 0) {
// I'd like this event to occur on the Second keydown
$('.div-2').fadeOut("slow");
$('.div-3').fadeIn("slow");
} else {
$('.div-1').fadeOut("slow");
$('.div-2').fadeIn("slow");
}
});
The only solution I can see is create local variable. In your case (slodeshow) you need to count each keydown and parse div class.
var hits = 0;
$(document).keydown(function() {
if (event.keyCode == '40') {
$('.div-' + hits).fadeOut("slow")
$('.div-' + (hits + 1)).fadeIn("slow")
hits++;
}
});

Detect double Ctrl keypress in JS

I have a custom CMS and would like to add a "shortcuts menu" triggered by the pressing of the Ctrl key twice within, say, 300 milliseconds.
I use prototype, so my starting point obviously is:
Event.observe(document, 'keypress', function(event)
{ if(event.keyCode == Event.KEY_XYZ) { show_shortcuts});
My approach at the moment would be populating a global variable with the current time in milliseconds, and checking on each keypress whether a keypress has happened less than 300 milliseconds ago.
But maybe there is a more elegant solution?
This should work. Maybe add some further checking if not some other key like Alt or Shift are pressed at the same time. Hope it is self explanatory, if not just ask and I provide clarification.
var dblCtrlKey = 0;
Event.observe(document, 'keydown', function(event) {
if (dblCtrlKey != 0 && event.ctrlKey) {
alert("Ok double ctrl");
dblCtrlKey = 0;
} else {
dblCtrlKey = setTimeout('dblCtrlKey = 0;', 300);
}
});
https://jsfiddle.net/3tc26g7x/
function doubleControlEvent() {
if (event.key === 'Control') {
timesCtrlClicked++
if (timesCtrlClicked >= 2) {
console.log('Double control')
// Double Crtl is clicked add your code here
}
setTimeout(() => (timesCtrlClicked = 0), 200)
}
}
let timesCtrlClicked = 0;
document.addEventListener('keyup', doubleControlEvent, true)

Categories

Resources