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

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

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

Disable arrow key page scrolling in Firefox

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.

Why doesn't preventDefault() stop focus change after a Tab-keypress?

I was fiddling with preventDefault() and must be doing something wrong.
$("#input").bind("keypress", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The tab functionality isn't prevented. What's wrong with this?
Try this FIDDLE. The input loses focus when you tab. Binding to the body fixes this.
$("body").on("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The keypress event is simply not fired when the Tab is pressed - this also explains why there is no alert, independent of what preventing the default may do.
Changing the code to use keydown allows the Tab to be caught and prevents the default focus-change (in Chrome1, anyway).
$("#input").bind("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
}
});
1 I tested the above in Chrome 35 with jQuery 1.6-2.1; it does not work under the KO 3.0 library.
From the documentation on JQuery,
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
This method is a shortcut for .on( "keypress", handler ) in the first two variations, and .trigger( "keypress" ) in the third.
The keypress event is sent to an element when the browser registers keyboard input. This is similar to the keydown event, except that modifier and non-printing keys such as Shift, Esc, and delete trigger keydown events but not keypress events. Other differences between the two events may arise depending on platform and browser.
So in this case you are using the wrong event. Also it might have browser compatibility issues.

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

Prevent default event action not working...?

I'm trying to add keyboard shortcuts on my website to make fast navigation possible using the keyboard. I'm running into a slight problem, however, with my attempted Alt+X shortcut. The event runs just fine and returns false as it should, but the browser's File menu comes up regardless. I've also tried the preventDefault method, but no change.
The cut-down version of the script is:
document.documentElement.onkeydown = function(e) {
e = e || window.event;
switch( e.keyCode || e.which) {
// some cases here - most notably:
case 116: // F5 key
if( activeFrame) {
activeFrame.contentWindow.location.reload();
// reloads an iframe if one is active
return false;
}
break;
// more cases...
case 88: // X key
if( e.altKey) {
// do something
return false;
}
}
}
As noted above, overriding the default action of the F5 key works just fine - the browser reloads the page only if no iframe is active. I don't quite see how to prevent the menu from appearing when Alt+X is pressed.
use stopPropagation(e); instead of preventDefault method
function stopPropagation(e)
{
e = e || event;/* get IE event ( not passed ) */
e.stopPropagation? e.stopPropagation() : e.cancelBubble = true;
}
Reference link
Another SO question which mentions that preventDefault has issue in IE.
UPDATE
Try using below code as per MSDN Reference
event.returnValue=false;
And some point from Detecting keystrokes
Some general caveats:
Generally, Mac is less reliable than Windows, and some keys cannot be detected.
Explorer doesn't fire the keypress event for delete, end, enter, escape, function keys, home, insert, pageUp/Down and tab.
Onkeypress, Safari gives weird keyCode values in the 63200 range for delete, end, function keys, home and pageUp.Down. The onkeydown and -up values are normal.
Alt, Cmd, Ctrl and Shift cannot be detected on Mac, except in Opera. However, you can always use the altKey, ctrlKey, and shiftKey properties.
I actually had a web app working just fine with CTRL shortcut keys, but then decided I'd be clever and use the accesskey attribute, and ran into this exact issue with IE.
The problem with going to CTRL shortcut keys is that many of those are more standard/useful across many applications (eg: cut, copy, paste, select all).
Ctrl+Alt is fairly safe, but requires more work on the user's part.
I tend to just try to stick to ALT shortcuts IE doesn't stubbornly insist on handling.
Demo of CTRL + A/CTRL + F being cancelled successfully:
http://jsfiddle.net/egJyT/
This answer seems to imply it isn't possible to disable the menu shortcuts without putting IE into kiosk mode.
Beware that if you manage to successfully prevent the browser from detecting a key combination you may make your page unusable for some users. Many screen readers have reserved almost any key you can think of to control the screen reader and if your page was accessible using a screen reader before you added the shortcut key code, it may be completely un-accessible users needing screen readers after you add it.
Read this article about access keys (a bit old but probably still relevant), and this article about Reserved Keystroke Combinations before you invest too much time on this problem.

Categories