Prevent default 'ctrl pageup' and 'ctrl pagedown' in Chrome - javascript

I have some code to create hotkeys for a web application. All of the hotkeys work in IE and Firefox, however Ctrl+PgUp and Ctrl+PgDn are not working in Chrome.
After digging around for answers and writing some custom test code, I believe I have determined that this is because those events fire, in Chrome, on keyup instead of keydown.
The default Chrome handlers for those events are firing instead of mine (or at least first) and switching the browser to the next or previous tab. If I use the hotkey to switch back to the tab with my application then my handlers catch the event.
So my question is, is there any way to catch these events in Chrome and prevent the default functionality from running?
The code in question is:
//These work in IE and Firefox
$(this).bind('keydown', 'ctrl+pageup', (evt) => {
this.prevPage();
return false;
});
$(this).bind('keydown', 'ctrl+pagedown', (evt) => {
this.nextPage();
return false;
});
//These catch the event in chrome, but it's too late
$(this).bind('keyup', 'ctrl+pageup', (evt) => {
this.prevPage();
return false;
});
$(this).bind('keyup', 'ctrl+pagedown', (evt) => {
this.nextPage();
return false;
});
It does exactly what I want in IE and Firefox, but not Chrome. I have tried evt.preventDefault(), evt.stopImmediatePropagation and evt.stopPropagation. However, it does not work (I believe because my handlers are being called after the browser handlers).

Check a similar question on this link:
Chrome - Javascript prevent default Ctrl + MouseWheel behavior
They say its impossible on chrome and its still being addressed!

Related

an issue with keyDown event in different browsers

so the thing is that 'keydown' event calls after the keyup event if multiple keys are pressed and released in particular order in chrome, but seems like there is no such issue in firefox browser
for example we have these events on window with if (e.repeat) return to prevent repeat
window.addEventListener('keydown', (e) => {
if (e.repeat) return
console.log(e.key, 'pressed')
})
window.addEventListener('keyup', (e) => {
console.log(e.key, 'released')
})
and here is the result of me pressing multiple keys at once and then releasing them one by one
firefox
chrome
any ideas of how to fix this? i think it has something to do with if (e.repeat) return and there is a better way to prevent this event repeat on button hold
I tried doing it on Chrome and Firefox, and it worked as predicted in both of them.
Could you please say what environment you are using this piece of code on?

ContextMenu event doesn't fire in mobile browsers

ContextMenu event doesn't work at cell phones? I use simple addEventListener("contextmenu", handler). It fires in Chrome Dev Tools, but doesn't fire in real cell phones. I tried it in Android and Windows Phone.
How to make it work?
What version of Chrome / Browser on Android and which version of Windows Phone are you using?
It may be worth adjusting your code to see if the document.addEventListener function is defined, if not then fallback to the older 'attachEvent' function.
Try this:
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
// handler
}, false);
} else {
document.attachEvent('oncontextmenu', function() {
//handler
});
}
Also, what is it you are trying to achieve by overwriting the default context menu behaviour?
When you say '...doesn't fire at real cell phones', does the document.addEventListener line not get hit, or does your handler function not execute correctly. Can you post your handle function code?

Prototype observe event problem in Opera

I'm using Prototype and doing Event.observe on window.document.
I'm catching enter (keyCode 13) and alt+f (altKey && keyCode=70).
My code is working super with firefox, IE and chrome. With Opera no. Enter is catched, but only if my focus is not in any text input. Alt+F is not working at all.
Is it bug in Prototype or I need to do something 'extra' on Opera in order to go on? As i said, in all other browser my code works....
Firstly, the following is a helpful resource: http://unixpapa.com/js/key.html
Secondly, you should know there is a difference between keydown (or keyup) and keypress. keypress does not typically allow modifier keys, though it does allow some in Opera like control. Better to use keydown for cross-browser consistency.
I get keyCode === 13 in Opera 11.10 no matter whether the textbox is entered or not, and no matter whether using Prototype like this:
Event.observe(document, 'keydown', function (e) {
alert(e.charCode+'::'+e.keyCode);
});
or using the native method directly (using attachEvent for IE):
if (document.addEventListener) {
document.addEventListener('keydown', function (e) {
alert(e.charCode+'::'+e.keyCode);
}, false);
}
else { // IE
document.attachEvent('onkeypress', function (e) {
alert(e.charCode+'::'+e.keyCode);
});
}
However, alt is indeed not detected inside a textbox unless combined with a control or function key (though that doesn't work in Chrome or IE). This may be because Windows uses alt to give access to the applications menu bar.
You could try using control key and using preventDefault() (to avoid default behaviors like ctrl-f doing a page find) though this might annoy your users who might not want their browser behaviors disabled for your page.
Alt-F activates the menu and Opera doesn't let JavaScript handle this key press.

Is there any way to use window.onbeforeunload on Mobile Safari for iOS devices?

Looks like Apple has disabled the window.onbeforeunload event for iOS devices (iPhone, iPad, iPod Touch). Unfortunately I can't find any documentation as to why this event doesn't work in Mobile Safari.
Does anyone know if there's a reliable alternative to this function? Android's browser appears to support it just fine, and the Safari desktop application also supports the onbeforeunload event without issue.
I see that it's an old question, but i faced this problem recently.
I'm using window.unload and it works fine in ios browsers (although if you look at Apple documentation it seems to be deprecated and they recommend to use document.pagehide)
If you really need it, you cant just get all links, forms and DOM objects that have a handler changing the url and make those wait until you've done what you want.
For the links, you get them by getElementsByTagName, check if the href starts with anything but a # and just add your onbeforeunload function add onclick (which will be invoked before the href is looked at).
Same for the forms but with onsubmit.
And finaly, for the elements changing the href with JavaScript, you should make sure when you add the lsitener that you call your onbeforeunlaod function (or, if you use DOM0 or DOM1 listeners, you can just add some class and then use a global script that checks all elements with the class and adds it to the event listener with a closure.
But you should normaly be able to avoid the use of this event (probably using cookies to store the thing you wanted to send every x seconds and allowing to, in the worst case, have a look at it next time the user loads a page and, in the best case, be able to send an Ajax request at onbeforeunload or onunload which, even if it sends only the http headers, woudl allow you to get what you want).
Based on Xavier's answer, I devised a solution along these lines:
function doStuff() {
// here goes your logic
}
function isSafariMobile() {
return navigator && /Safari/.test(navigator.userAgent) && /iPhone|iPad/.test(navigator.userAgent)
}
function addWatcherToLinks(baseNode) {
if (!baseNode || !baseNode.querySelectorAll) { return; } // ignore comments, text, etc.
for (const link of baseNode.querySelectorAll("a")) {
link.addEventListener('click', doStuff);
}
for (const form of baseNode.querySelectorAll("form")) {
form.addEventListener('submit', doStuff);
}
}
// ...when the page loads...
// we watch the page for beforeunload to call doStuff
// Since Safari mobile does not support this, we attach a listener (watcher) to each link and form and then call doStuff.
// Also, we add such a watcher to all new incoming nodes (DOMNodeInserted).
if (isSafariMobile()) {
addWatcherToLinks(document);
window.addEventListener("DOMNodeInserted", (event) => { addWatcherToLinks(event.target); }, false);
} else {
window.addEventListener('beforeunload', doStuff);
}
This solution has some limitations. The biggest one is that it attaches itself to all forms and all links. Sometimes this might not be desired. If you need it you can skip some nodes (e.g. mark them with a particular data- attribute).
I was having the same problem. it seems safari browser in iphone triggers only focus and blur events and almost every other event is not triggered, e.g.(pagehide, pageshow, visibility change) but the good news is focus and blur event are supported and triggered on iphone, ipad & android mobiles as well.
window.addEventListener('focus', function(){
// do stuff
});
window.addEventListener('blur', function(){
// do stuff
});
hope this helps anyone.

`return false` in an event handler attached by addEventListener or element.on*

Right let’s get this out the way first. Yes, I want to hide the context menu. No, I’m not trying to prevent someone lifting content off my page. Its intended use is input for an in-browser game and it will be limited to a specific area on the webpage.
Moving from the ideological to the technical...
var mouse_input = function (evt) {
// ...
return false;
}
document.onmousedown = mouse_input; // successful at preventing the menu.
document.addEventListener('mousedown', mouse_input, true); // unsuccessful
Could someone explain to me why the addEventListener version is unable to stop the context menu from firing? The only difference I was able to see in Safari's Web Inspector was that document.onmousedown had a isAttribute value that was true whilst the addEventListener version had the same value as false.
So my unfruitful search suddenly became fruitful.
var mouse_input = function (evt) {
evt.preventDefault();
}
document.addEventListener('contextmenu', mouse_input, false);
Works for Safari, Firefox, Opera. preventDefault() stops the usual actions from happening. I had to change the event that was listened for to accommodate for Safari and it is more logical anyway. Further information: functions that implement EventListener shouldn’t return values so return false had no effect.
To explain the difference .. element.onmousedown = somefunction; is an absolute assignment; you are replacing the event handler on the element. element.addEventListener(...) is, as the name implies, adding a handler in addition to any handler(s) already attached for the event.

Categories