Disable arrow key page scrolling in Firefox - javascript

I have a project where the arrow keys can be used as a method of input, in most browsers simply using .preventDefault() works perfectly, however Firefox (v37 on both Win8 and OSX) still seems to move the browser window (If there's available off screen scroll-able area)
$(document).keyup(function (evt) {
if (evt.keyCode == 39 || evt.keyCode == 40) { // Right arrow, Down arrow
evt.preventDefault();
// Actual code
} else {
if (evt.keyCode == 37 || evt.keyCode == 38) { // Left arrow, Up arrow
evt.preventDefault();
// Actual code
}
}
})
I've seen some things about using charCode, however my code does run so the .preventDefault() is defiantly being hit.
As far as I can tell, there's no reason this should move the window position.
Am I doing something wrong? Or if not, is there another way to disable the window moving due to arrow keys?

You have to listen keydown event instead of keyup cause the former is always happened prior to the latter. This mean that browser may respond to keydown event before keyup event is happened. In this case you cannot cancel browser's response action (i.e. scrolling) from keyup listener anymore.

Related

Find unknown active event listeners Javascript

I would like to find unknown event listeners
So far I tried to locate all event listeners based on This post but it did not work:
getEventListeners(Element);
and
'Chrome Developer tools > Elements > Event listeners'
Are there other ways to detect active event listeners?
The reason for asking this is:
I'm building the 2D breakout game using pure JavaScript based on the tutorial from Mozilla and managed to enhance it with various features and multiple levels.
I have a set of added event listeners and also a function that removes them, so far everything works fine.
I do not have an event listener for keycode 13(which is the enter key)
The problem is that if I press the Enter key while the animation is ongoing on the canvas, it changes the behavior with increasing the speed of the ball after each keypress and ultimately it renders a different drawing.
If I don't press the Enter key everything works as intended.
The only event listener that increases the speed is a 'click' event, but that is removed immediately after the function is executed, and it shouldn't interfere with the game.
The other problem is that through the above-mentioned methods there are no event listeners found, not even the ones I added myself, albeit they still work.
I could not find anything that relates to that unwanted behavior and I would like to ask if there are other ways to view the active event listeners.
Here is the code I'm working on
[EDIT:
After realising that the bug was coming from a keydown event, adding preventDefault() solved the problem.
However, I'm not sure why did this behaviour occur when there was no e.keyCode == 13 setup in the first place and why did the preventDefault() method solve the issue.
]
My guess is the click event is giving focus to giraffe allowing it to be fired with the enter key. You can try mousedown and preventDefault to keep giraffe from taking focus:
giraffe.addEventListener('mousedown', function(e){
e.preventDefault();
giraffe.classList.remove('pulsate');
setTimeout(function(){
giraffe.classList.add('pulsate');
}, 0);
yahoo.play();
});
It seems that the bug lays in the keydown event handler (keyDownHandler). This is what was causing the unexpected behaviour.
The bug disappeared after adding e.preventDefault(); to keyDownHandler function.
Original:
function keyDownHandler(e) { //on key down
e.keyCode == 37 ? leftPressed = true : null;
e.keyCode == 39 ? rightPressed = true : null;
}
After:
function keyDownHandler(e) { //on key down
e.preventDefault();
e.keyCode == 37 ? leftPressed = true : null;
e.keyCode == 39 ? rightPressed = true : null;
End result: Nothing happens when pressing the Enter Key
Credit to #Joe Fitzsimmons for pointing me in the right direction

Javascript onKeyDown function

I have written a simple javascript code and added event listener for onKeyDown/onKeyUp . It works just fine and detects the Control key as required. However the Control key shows pressed even when I am using OS shortcuts.
To be specific I am on Ubuntu and use Ctrl+Alt+ arrow keys to switch workspaces. So when I switch the workspace and come back to Chrome, it shows Control key pressed already.
I dont mind it but even when the shortcut keys are released, onkeyup method is not called and hence the status shows Ctrl key pressed.
How do I avoid this?
Below is my code:
function keypressedfn(e){
if(e.which == CTRL_KEY){
console.log("isCtrl pressed");
isCtrl=true;
if(isWheel){
e.preventDefault();
e.stopPropagation();
}
}
};
function keyreleasedfn(e){
if(e.which == CTRL_KEY){
console.log("isCtrl released");
isCtrl=false;
isWheel=false;
}
};
$(document).ready(function(){
$(document).keydown(keypressedfn);
$(document).keyup(keyreleasedfn);
});
if you're using Ctrl to change workspaces, then your window w/ js running is losing focus before the keyup event.
you could bind an event to the window object that discards keydown whenever the window loses focus:
window.onblur = function(){console.log("blur");};
without seeing more of your code i can't say much more than that
It is not standard practice to detect the KeyDown event of Control key (or Alt, or Shift, for that matter).
What you should do is find if your desired key is pressed. For example, if you want to save something when Ctrl+S is pressed, look for S key.
var keyCode = (e.which) ? e.which : e.keyCode; // keyCode will be 'S'
if (e.ctrlKey && keyCode == 83) {
// Ctrl + S pressed. Do stuff.
}

How can I prevent Ctrl-- and Ctrl-+?

Google Chrome has the key binding Ctrl-- for decreasing font size and and Ctrl-+ for increasing font size. I want to prevent them. I figured out that they are bound to <body>, and I did:
document.body.addEventListener('keyup',
function(obj, e){e.preventDefault();}, false);
but it seems that in/decreasing font size is triggered before the event is sent to these handlers, and by the time preventDefault() is run, they are already done, and my attempt fails. How can I prevent these default bindings?
To (potential) downvoters: Read my question above carefully. I never wrote that I want to prevent zooming entirely. I want to unbind these functions from the particular key combinations that I mention. And if you think freeing Ctrl-- should not be done, then why does the Ace editor ships emacs keybinding with Ctrl-- bound to undo? Are you claiming that the developers of Ace editor (including Mozilla Firefox developers, among others) are doing something useless? Are you saying that you are superior than them? And even if your suggestion is not to do it, why downvote instead of writing that as an answer?
If you bind to the keydown event and you use e as the first argument, this code will work:
document.body.addEventListener('keydown', function(e) {
e.preventDefault();
}, false);
Demonstration
Note that this method does nothing to disable the browser's zoom feature, it just prevents the default behavior of all keyboard shortcuts. For example, you can still zoom with Ctrl+mouse wheel.
This one uses jQuery and checks to see if: the Ctrl key is pressed and the +/- buttons are pressed.
$(document).keydown(function(e) {
if(e.ctrlKey
&& (e.which == 107 || e.which == 109 || e.which == 187 || e.which == 189))
{
e.preventDefault();
return false;
}
});

Will this JavaScript code affect other keypress events too by disabling one key?

I'm using this to disable the 'scrolling' effect the spacebar has in a browser. Will this affect other keypress events too?
window.onkeydown = function(e) {
return !(e.keyCode == 32);
};
Could someone please explain what this is doing? I'm not sure if this code is bad, but it seems to disable other keypress related codes in my page, and I want to make sure this isn't the reason.
Thanks!
ASCII code 32 is the ASCII value that represents the spacebar key, and your code is essentially telling the browser to return false whenever that keycode is detected. Since false is returned, the scrollbar effect you speak of is in fact successfully disabled.
However, the unfortunate side effect of this convenient spacebar-scroll-disabling function is that it disables spacebar keypresses everywhere on the page.
Instead of returning false, if the keycode is detected, pass the current scrollTop value into a closure that returns a function to a setTimeout event. When the setTimeout fires, the scrollTop position is reset back to the value it was in when the setTimeout event was first registered.
window.onkeydown = function(e) {
if(event.keyCode == 32) { // alert($(document).scrollTop() );
setTimeout(
(function(scrollval) {
return function() {
$(document).scrollTop(scrollval);
};
})( $(document).scrollTop() ), 0);
}
};
Your users can still conveniently make use of spacebars in input textboxes and textareas, and at the same time, pressing the spacebar key while not focused on a text element will no longer result in the page scrolling.
Under the hood, the scroll is still taking place. It's just being reset at a rate fast enough to where the user doesn't notice.
If you increase this value to 100 or 1000, it will give you a better idea of what is going on under the hood. You'll actually see the page scroll and then get set back to the previous scroll position.
This was only tested in Chrome and Firefox 13! So you may have to adjust the setTimeout duration -- currently 0 -- to a different value in browsers like Internet Explorer. Be prepared to gracefully degrade -- by supporting this feature only in modern browsers -- if necessary.
UPDATE:
For reference, below is the method to use to make this compatible in the major browsers. It has been tested in Chrome, Firefox, IE8, IE9, and Safari.
While it does work in IE8/IE9, it isn't very smooth.
// put the eventhandler in a named function so it can be easily assigned
// to other events.
function noScrollEvent(e) {
e = e || window.event;
if(e.keyCode == 32) {
setTimeout(
(function(scrollval) {
return function() {
$(document).scrollTop(scrollval);
};
})( $(document).scrollTop() ), 0);
}
}
// Chrome and Firefox must use onkeydown
window.onkeydown = noScrollEvent;
// Internet Explorer 8 and 9 and Safari must use onkeypress
window.document.onkeypress = noScrollEvent;
If another element is bound to the keydown event it will not be effected by this code
See my fiddle and try adding and remove the textarea listening to the keydown event
window.onkeydown = function(e) {
return !(e.keyCode == 32);
};
document.getElementsByTagName("textarea")[0].onkeydown = function(e) {
alert("hi");
}
http://jsfiddle.net/HnD4Y/
The answer above with the setTimeout did not work for me at all on Chome with a delay of 0. With a delay bumped above 50ms, it began to work, but that caused a noticeable page jump. I believe that setTimeout was scrolling the page up too early, then Chrome moved it down later.
Below is my solution that is working well. It returns false on the keydown event to prevent the browser from doing a page-down. Then you make sure event you set up on your button etc. to use the keyup event instead.
$(mySelector).keyup(eventHandlerFunction);
[dom element].onkeydown = function(event) {
if (event.keyCode == 32) {return false;}
};
Note: input fields will not reflect spacebar key events if they or their parent are covered by this onkeydown handler

How can I prevent the browser's default history back action for the backspace button with JavaScript?

Is there a way to prevent the default action from occurring when the user presses backspace in a browser?
I don't need to prevent the user from leaving, just from having the default backspace action. I need the backspace to do something different (it's a game).
I tried without success:
window.addEventListener('keydown', function(e) {
if (e.keyCode === Game.Key.BACK_SPACE)
{
e.preventDefault();
e.stopPropagation();
return false;
}
}, false);
If I put an alert inside the if, the alert will be shown for backspace key press. So, the keyCode is correct.
This has to work in Opera 10.6, Firefox 4, Chrome 6, Internet Explorer 9 and Safari 5.
You don't need return false or e.stopPropagation(); neither will make any difference in a listener attached with addEventListener. Your code won't work in Opera, which only allows you to suppress the default browser behaviour in the keypress event, or IE <= 8, which doesn't support addEventListener. The following should work in all browsers, so long as you don't already have keydown and keypress event handlers on the document.
EDIT: It also now filters out events that originated from an <input> or <textarea> element:
function suppressBackspace(evt) {
evt = evt || window.event;
var target = evt.target || evt.srcElement;
if (evt.keyCode == 8 && !/input|textarea/i.test(target.nodeName)) {
return false;
}
}
document.onkeydown = suppressBackspace;
document.onkeypress = suppressBackspace;
If you prefer to simply have the fix for yourself, without affecting other users when scripting into the web page, read below.
Here's some solutions that only change the browser you are using:
- Firefox on Linux "unmapped" the backspace behavior since 2006 so it's not affected; (at any rate, it was simply set to scroll up before then)
- Chrome has just announced that it will do the same from now on; (http://forums.theregister.co.uk/forum/1/2016/05/20/chrome_deletes_backspace/)
- Firefox on Windows can be set to ignore backspace by going into about:config and changing the backspace_action setting to 2; (http://kb.mozillazine.org/Browser.backspace_action)
- Safari ?!
I found at Telerik's page script ready to use. Script blocks back button action: by clicking in browser back button and backspace on page. This script works. I'm using it in my project.
http://www.telerik.com/community/code-library/aspnet-ajax/general/disable-backspace-from-master-page.aspx

Categories