Disable Browser Shortcut Keys - javascript

I am trying to create, essentially, a 'kiosk'
I have an web application that I want to be the only thing accessible on screen. I know chrome has a 'kiosk' mode (shortcut: chrome.exe --kiosk www.url.com). That takes care of the auto-fullscreen, but disables very few shortcuts (perhaps only f11).
With a bit of help from the internet, I wrote out some javascript that gets most of the job done. The code is as follows:
window.onload = function() {
window.document.body.onkeydown = function() {
if (event.ctrlKey) {
event.stopPropagation();
event.preventDefault();
try {
event.keyCode = 0; // this is a hack to capture ctrl+f ctrl+p etc
}
catch (event) {
}
return false;
}
return true; // for keys that weren't shortcuts (e.g. no ctrl) then the event is bubbled
}
}
This takes care of things like ctrl+f, ctrl+p, etc. Unfortunately, it does not disable shortcuts such at ctrl+t, ctrl+n, f5, etc.
Is it even possible to disable these, or am I chasing a rainbow here? I don't care if it's javascript, settings, whatever, but I would really like to do it without a plugin.

You can disable any keys you want via javascript. You just need to know the key code for them.

Related

Any way to override Ctrl+N to open a new window in Chrome?

I use a web app for work, and one of the shortcuts I use often is Ctrl+M. However, I'm often typing very quickly and mistakenly hit Ctrl+N by mistake, and instead of triggering an action in my web app, I open up a new window. I would like to be able to prevent that, but I can't seem to figure out how. So far I've tried running this code every time the page loads, but it doesn't seem to do anything. (Ignore the fact that I'm using a switch for just one key, I have a few other custom Ctrl shortcuts that don't override Chrome shortcuts that are working, I just removed them for readability)
document.onkeydown = function(e)
{
if(e.ctrlKey === false)
{
return;
}
switch(e.which) {
case 78:
//just to keep from opening a new tab when merging cells
e.preventDefault();
e.stopPropagation();
break;
default:
return;
}
};
There is no way to override Ctrl+N, Ctrl+T, or Ctrl+W in Google Chrome since version 4 of Chrome (shipped in 2010).
As stated on the Chromium issue tracker:
In Chrome4, certain control key combinations have been reserved for browser usage only and can no longer be intercepted by the client side JavaScript in the web page.
Only known workaround is to open your webpage/extension as a Chrome app where it will again have permission to override these blacklisted key combos
You can find a github issue by the GateOne project discussing the same problem here.
They say the only workaround is to "Create an application shortcut" where you can now override the Ctrl+N key.
Under Linux one can disable the combination by redefining the keyboard mapping at the Xorg level. Then it will be disabled for all applications running under X in the current session. It is often useful to disable various control combinations in a kiosk-type app running in fullscreen mode. For example, your .xinitrc could set the custom keyboard mapping:
#!/usr/bin/env bash
test -f ~/.Xkeymap && xkbcomp ~/.Xkeymap $DISPLAY &
while :; do
/usr/lib/chromium-55.0.2866.0-16k/chrome-wrapper \
--disable-seccomp-filter-sandbox --user-data-dir=.chromium-55.0.2866.0-16k \
--app="http://1.1.1.1:10001/terminal/start" --start-fullscreen \
--kiosk --window-position=0,0 --window-size=1920,1080
done
where your modified .Xkeymap would remap <LatN> key to something harmless like <F3> when used in combination with <Ctrl> and other modifier keys:
type "MYCONTROL" {
modifiers= Shift+Lock+Control+Alt+LevelThree;
map[Shift]= Level2;
map[Lock]= Level2;
map[Alt]= Level3;
map[LevelThree]= Level4;
map[Shift+LevelThree]= Level5;
map[Control+Alt]= Level6;
map[Control]= Level7;
map[Shift+Control]= Level8;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
level_name[Level3]= "Alt Base";
level_name[Level4]= "L3 Base";
level_name[Level5]= "Shift L3";
level_name[Level6]= "Ctrl+Alt";
level_name[Level7]= "Ctrl Base";
level_name[Level8]= "Shift+Ctrl";
};
...
key <LatN> {
type= "MYCONTROL",
symbols[Group1]= [ n, N, F3, F3, F3, F3, F3, F3 ]
};

visibilitychange event is not triggered when switching program/window with ALT+TAB or clicking in taskbar

The problem is with the behaviour of the event "visibilitychange".
It's triggered:
- When I switch to a different tab inside the browser window.
When I click in minimize / restore buttons for the browser window.
(this is ok)
It's not triggered:
- When I switch to a different window/program using ALT+TAB.
When I switch to a different window/program clicking on taskbar.
(this SHOULD trigger, because, just like when minimizing, the window's visibility may change)
W3 Page Visibility API Documentation: http://www.w3.org/TR/page-visibility/
There is no definition of "page visibility" regarding ALT+TAB/program switching in the spec sheet. I'm guessing it has something to do in between the OS and the Browser.
TESTED IN
Browsers:
Chrome 40.0.2214.115 m / Firefox 36.0.1 / Internet Explorer 11.0.9600.17107
OS: Windows 8.1
Is there a workaround to fix this behaviour? The implementation is fairly simple, I listen to the "visibilitychange" event using jQuery, and then in its callback, I check for the value of "document.visibilityState", but the problem is that the event is not firing when expected.
$(document).on('visibilitychange', function() {
if(document.visibilityState == 'hidden') {
// page is hidden
} else {
// page is visible
}
});
This can be done without jQuery too, but the ALT+TAB and taskbar switch hide/show expected behaviour is still missing:
if(document.addEventListener){
document.addEventListener("visibilitychange", function() {
// check for page visibility
});
}
I've also tried the ifvisible.js module (https://github.com/serkanyersen/ifvisible.js) but the behaviour is the same.
ifvisible.on('blur', function() {
// page is hidden
});
ifvisible.on('focus', function() {
// page is visible
});
I haven't tested in other browsers because if I can't make it work in Chrome on Windows I really don't care about the other browsers yet.
Any help or suggestions?
UPDATE
I tried using different vendor prefixes for the event name (visibilitychange, webkitvisibilitychange, mozvisibilitychange, msvisibilitychange) but but still the event is not triggered when I switch to a different program in the taskbar or ALT+TAB, or even if I open the start menu thing in windows with the windows key, which covers the whole screen.
I can reproduce the exact same issue in Chrome, Firefox and Internet Explorer.
UPDATE #2
Here's a roundup post I wrote for this issue and a workaround in pure Javascript to solve the encountered problems.
UPDATE #3
Edited to include a copy of the sourced blog post. (see accepted answer)
Here's a roundup post I wrote for this issue and a workaround in pure JavaScript to solve the encountered problems.
Edited to include a copy of the sourced blog post:
In any kind of javascript application we develop there may be a
feature or any change in the application which reacts according to the
current user visibility state, this could be to pause a playing video
when the user ALT+TABs to a different window, tracking stats about how
the users interact with our application, how often does him switch to
a different tab, how long does it take him to return and a lot of
performance improvements that can benefit from this kind of API.
The Page Visibility API provides us with two top-level attributes:
document.hidden (boolean) and document.visibilityState (which could be
any of these strings: “hidden”, “visible”, “prerender”, “unloaded”).
This would not be not good enough without an event we could listen to
though, that’s why the API also provides the useful visibilitychange
event.
So, here’s a basic example on how we could take action on a visibility
change:
function handleVisibilityChange() {
if(document.hidden) {
// the page is hidden
} else {
// the page is visible
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
We could also check for document.visibilityState value.
Dealing with vendor issues George Berkeley by John Smibert
Some of the implementations on some browsers still need that the
attributes or even the event name is vendor-prefixed, this means we
may need to listen to the msvisibilitychange event or check for the
document.webkitHidden or the document.mozHidden attributes. In order
to do so, we should check if any vendor-prefixed attribute is set, and
once we know which one is the one used in the current browser (only if
there’s the need for a prefix), we can name the event and attributes
properly.
Here’s an example approach on how to handle these prefixes:
var browserPrefixes = ['moz', 'ms', 'o', 'webkit'];
// get the correct attribute name
function getHiddenPropertyName(prefix) {
return (prefix ? prefix + 'Hidden' : 'hidden');
}
// get the correct event name
function getVisibilityEvent(prefix) {
return (prefix ? prefix : '') + 'visibilitychange';
}
// get current browser vendor prefix
function getBrowserPrefix() {
for (var i = 0; i < browserPrefixes.length; i++) {
if(getHiddenPropertyName(browserPrefixes[i]) in document) {
// return vendor prefix
return browserPrefixes[i];
}
}
// no vendor prefix needed
return null;
}
// bind and handle events
var browserPrefix = getBrowserPrefix();
function handleVisibilityChange() {
if(document[getHiddenPropertyName(browserPrefix )]) {
// the page is hidden
console.log('hidden');
} else {
// the page is visible
console.log('visible');
}
}
document.addEventListener(getVisibilityEvent(browserPrefix), handleVisibilityChange, false);
Other issues There is a challenging issue around the “Page Visibility”
definition: how to determine if the application is visible or not if
the window focus is lost for another window, but not the actual
visibility on the screen? what about different kinds of visibility
lost, like ALT+TAB, WIN/MAC key (start menu / dash), taskbar/dock
actions, WIN+L (lock screen), window minimize, window close, tab
switching. What about the behaviour on mobile devices?
There’s lots of ways in which we may lose or gain visibility and a lot
of possible interactions between the browser and the OS, therefore I
don’t think there’s a proper and complete “visible page” definition in
the W3C spec. This is the definition we get for the document.hidden
attribute:
HIDDEN ATTRIBUTE On getting, the hidden attribute MUST return true if
the Document contained by the top level browsing context (root window
in the browser’s viewport) [HTML5] is not visible at all. The
attribute MUST return false if the Document contained by the top level
browsing context is at least partially visible on at least one screen.
If the defaultView of the Document is null, on getting, the hidden
attribute MUST return true.
To accommodate accessibility tools that are typically full screen but
still show a view of the page, when applicable, this attribute MAY
return false when the User Agent is not minimized but is fully
obscured by other applications.
I’ve found several inconsistencies on when the event is actually
fired, for example (Chrome 41.0.2272.101 m, on Windows 8.1) the event
is not fired when I ALT+TAB to a different window/program nor when I
ALT+TAB again to return, but it IS fired if I CTRL+TAB and then
CTRL+SHIFT+TAB to switch between browser tabs. It’s also fired when I
click on the minimize button, but it’s not fired if the window is not
maximized and I click my editor window which is behing the browser
window. So the behaviour of this API and it’s different
implementations are still obscure.
A workaround for this, is to compensate taking advantage of the better
implemented focus and blur events, and making a custom approach to the
whole “Page Visibility” issue using an internal flag to prevent
multiple executions, this is what I’ve come up with:
var browserPrefixes = ['moz', 'ms', 'o', 'webkit'],
isVisible = true; // internal flag, defaults to true
// get the correct attribute name
function getHiddenPropertyName(prefix) {
return (prefix ? prefix + 'Hidden' : 'hidden');
}
// get the correct event name
function getVisibilityEvent(prefix) {
return (prefix ? prefix : '') + 'visibilitychange';
}
// get current browser vendor prefix
function getBrowserPrefix() {
for (var i = 0; i < browserPrefixes.length; i++) {
if(getHiddenPropertyName(browserPrefixes[i]) in document) {
// return vendor prefix
return browserPrefixes[i];
}
}
// no vendor prefix needed
return null;
}
// bind and handle events
var browserPrefix = getBrowserPrefix(),
hiddenPropertyName = getHiddenPropertyName(browserPrefix),
visibilityEventName = getVisibilityEvent(browserPrefix);
function onVisible() {
// prevent double execution
if(isVisible) {
return;
}
// change flag value
isVisible = true;
console.log('visible}
function onHidden() {
// prevent double execution
if(!isVisible) {
return;
}
// change flag value
isVisible = false;
console.log('hidden}
function handleVisibilityChange(forcedFlag) {
// forcedFlag is a boolean when this event handler is triggered by a
// focus or blur eventotherwise it's an Event object
if(typeof forcedFlag === "boolean") {
if(forcedFlag) {
return onVisible();
}
return onHidden();
}
if(document[hiddenPropertyName]) {
return onHidden();
}
return onVisible();
}
document.addEventListener(visibilityEventName, handleVisibilityChange, false);
// extra event listeners for better behaviour
document.addEventListener('focus', function() {
handleVisibilityChange(true);
}, false);
document.addEventListener('blur', function() {
handleVisibilityChange(false);
}, false);
window.addEventListener('focus', function() {
handleVisibilityChange(true);
}, false);
window.addEventListener('blur', function() {
handleVisibilityChange(false);
}, false);
I welcome any feedback on this workaround. Some other great sources
for ideas on this subject:
Using the Page Visibility API Using PC Hardware more efficiently in
HTML5: New Web Performance APIs, Part 2 Introduction to the Page
Visibility API Conclusion The technologies of the web are continuously
evolving, we’re still recovering from a dark past where tables where
the markup king, where semantics didn’t mattered, and they weren’t any
standards around how a browser should render a page.
It’s important we push these new standards forward, but sometimes our
development requirements make us still need to adapt to these kind of
transitions, by handling vendor prefixes, testing in different
browsers and differents OSs or depend on third-party tools to properly
identify this differences.
We can only hope for a future where the W3C specifications are
strictly revised, strictly implemented by the browser developer teams,
and maybe one day we will have a common standard for all of us to work
with.
As for the Page Visibility API let’s just kinda cite George Berkeley
and say that:
“being visible” is being perceived.
A working solution is proposed described here: https://stackoverflow.com/a/9502074/698168. It uses a combination of the W3C Page Visibility API, blur/focus and mouse movements. Hidden HTML pages related to Alt+Tab are identified in a probabilistic way (i.e. you cannot determine if your page is hidden with 100% accuracy).
we can do like below when switching between tabs and switching between applications
var pageVisible = true;
function handleVisibilityChange() {
if (document.hidden) {
pageVisible = false;
} else {
pageVisible = true;
}
console.log("handleVisibilityChange")
console.log("pageVisible", pageVisible)
// some function call
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
window.addEventListener('focus', function() {
pageVisible = true;
// some function call
}, false);
window.addEventListener('blur', function() {
pageVisible = false;
// some function call
}, false);
There's a very simple solution to this I have come across.
You just need to pass false to the useCapture while attaching an event listener to the document. Works like a charm!
document.addEventListener('visibilitychange', function () {
// code goes here
}, false)

is it possible to bind ctrl+s on click event in javascript?

I am trying to write a code to bind the save as option on click event.I don't want to use filesaver.js. I want pure javascript to write this code.
HTML5 standards introduced the File API, which should allow scripts to offer up "files" (Blobs) for users to save. Support is shoddy, though, which is why polyfills like FileSaver.js exist. Filesaver.js is "pure" javascript, too, so I'm not sure why needing a pure javascript solution precludes its use (unless you mean you can't load outside scripts - just minify and inline it (along with licence, etc.)) Right now, if you must code it yourself, any cross-browser solution you come up with is likely to be an effective rewrite of the polyfil.
Once you have an implementation of saveAs(), simply attach it to whatever event trigger you like:
myButton.addEventListener( 'click', function() { window.saveAs( fileBlob, 'filename.txt' ) } );
Clarification: As per the W3C spec on Events, all untrusted events (includes key-press events) act as if event.preventDefault() was called - so there is explicitly no way to simulate an actual ctrl+s keypress - only ways to simulate its effects.
You could do something like this:
var isCtrlPressed = false;
function onKeyDown(event) {
if (event.keyCode == 17) { // Control got pressed
isCtrlPressed = true;
}
if (event.keyCode == 83) { // "s" got pressed
// if control is pressed too execute some code
if (isCtrlPressed) {
// Your code here
}
}
}
function onKeyUp(event) {
if (event.keyCode == 17) { // Control got pressed
isCtrlPressed = false;
}
}
Then on your body tag add the following events:
<body onkeydown="onKeyDown(event)" onkeyup="onKeyUp(event)">
</body>
You can find a lifedemo here:
http://jsbin.com/eBIRAfA/1/edit

Escape key stops loading the web application

Hi we are facing the problem with escape key in our web application. If user press the escape key the web application gets stop loading.
I tried using all these with(onkeydown and onkeyup)
document.attachEvent("onkeydown", win_onkeydown_handler);
window.attachEvent("onkeydown", win_onkeydown_handler);
window.document.attachEvent("onkeydown", win_onkeydown_handler);
I cant able detect the escape(KeyCode=27) in my web application .. but i am able to detect refresh,f5 and all other keys
Note: i face this problem in IE
This helps me to prevent escape in iframe
function disableEscapeAndRefresh(){
try{
if(window.frames && window.frames[0]){
window.frames[0].focus();
for (var i_tem = 0; i_tem < window.frames.length; i_tem++){
if(document.all && document.body.filters)
window.frames[i_tem].document.onkeydown = new Function("var e=window.frames["+i_tem+"].event; if(e.keyCode==116){e.keyCode=0;alert('Refresh Not Allowed');return false;}if(e.keyCode==27){e.keyCode=0;alert('Escape Not Allowed');return false;};");
}
}
}catch(e){
}
}
call this method in iframe onload
I don't think there's any way to trap that... it's the equivalent of clicking the X to stop the page loading.
Assuming that you are targeting versions of IE that have attachEvent enabled, you can use this to detect the escape key being pressed. The handling of the event is the usual code for preventing default event behaviour, though this may not work on cancelling the page download as this may be seen as a security flaw (imagine the unscrupulous developer that wants to prevent the user from cancelling a malicious download):
document.attachEvent('onkeydown', function(){
if(window.event.keyCode == 27) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
});
http://jsfiddle.net/steveukx/LJHs8/

Binding keys with javascript while preventing the browser shortcut keys

I'm making a javascript game and need to bind a lot of keys to different functions. This I know how to do, what I need some help on is over-riding the shortcut keys for the browser. in other-words I want to blur hot keys for the browser and divert them to my application.
I believe that if you stop the propogation of the event, then you will prevent the browser from catching the event.
an example of this:
element.onkeyup = function(e) {
var ev = e || event;
//do stuff here, probably with ev.keyCode
return false;
}

Categories