Handling Combo Keyboard Shortcuts - javascript

I want to simulate GMail/Twitter keyboard shortcuts of pressing a key, followed by another key to navigate somewhere in jQuery.
For example, G then H to go "Home" in GMail. Twitter also has G then H and other "combo" shortcuts.
Is there a jQuery plugin that simulates this behaviour?

I just released a library last week called mousetrap that has this functionality built in. Check out http://craig.is/killing/mice
You can do
Mousetrap.bind('g h', function() {
console.log('go home!');
});

Not sure about plugins, but you can achieve this other wise by keeping a key queue and processing that queue on each mouseup.
i.e. Something like:
var myKeyQueue = [];
$(document).keydown(function(e) {
var code e.charCode != 0 ? e.charCode : e.keyCode;
myKeyQueue.push(code);
});
$(document).keyup(function(e) {
processKeyQueue();
});
And you processKeyQueue function will be something like:
function processKeyQueue() {
// check if the Q contains any actionable key-combo, if so do it!
/*
if(myKeyQueue.length == 2) {
if(String.fromCharCode(myKeyQueue[0]) == 'G' && String.fromCharCode(myKeyQueue[0]) == 'H') {
// you code here ...
}
}
*/
if(myKeyQueue.length >= 2) {
myKeyQueue = []; // remove all keys in Q
}
}

Check out this Doing key combos with jQuery / JavaScript I think that it will answer your problem. Also this guy wrote his own VERY small plugin to handle CTRL+[Any Key] listener so that he could use shortcuts like CTRL+S to call a function that saves the active document, it might be able to be modified for your use

I think this: http://www.openjs.com/scripts/events/keyboard_shortcuts/
might help in some way for adding your own shotcuts

Related

How to get platform specific info for shortcuts?

How can I get platform specific shortcut, or key binding for a specific process?
As an example how can I get the information that on Windows shortcut for copying is Ctrl + C ? (I'd like the information on all of the tagged languages if possible) I mean both text editing and file manager usage, and also would like to know if they're independent.
If I understand you, you want rewrite system command of browser. In browser all process start after some event. You can copy text , if you use command for copy: document.execCommand('copy'); and you can rewrite all events except paste.
Example:
document.addEventListener('keydown', (ev) => {
if(ev.keyCode === 67 && ev.ctrlKey === true) { // ctrl+c
console.log(ev);
ev.preventDefault();//block default action of browser
}
});
and trigger copy:
document.addEventListener('keydown', (ev) => { //ctrl+z
if(ev.keyCode === 90 && ev.ctrlKey === true) {
console.log(ev);
document.execCommand('copy');
ev.preventDefault();
}
});
All execCommand: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
To expand on my comment above, you need to check for evt.metaKey to catch standard macOS shortcuts, which use the same letter keys for the basic Cut/Copy/Paste/Undo as Windows (X/C/V/Z), but combined with the different command (⌘) modifier key.
It doesn't hurt in most cases if a Mac user can also use their control key as well as the command key for a shortcut, so the easiest solution is to check for both. Here's code from the previous answer modified to do that:
document.addEventListener('keydown', (ev) => {
if (ev.keyCode === 67 && (ev.ctrlKey || ev.metaKey)) { // Copy shortcut
console.log(ev);
ev.preventDefault(); // block default action of browser
}
});
On a Windows system, you'll probably never see a keyboard event with metaKey being true, because as far as I can tell, any keypress using the Win key (⊞), which theoretically maps to metaKey, will be intercepted by Windows before a web browser has any chance to look at it.
If you want to explore more about key events and modifier keys, I threw together a quick CodePen here for that: https://codepen.io/kshetline/pen/MWmKrPM?editors=1010

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

How to override Ctrl + N in firefox to launch AJAX

Note: Juan Mendes answer is the selected answer because it had the most useful response to my situation. Though AxGryndr also had some useful information. Read both answers and they are both good for different situations. Thank you both for helping with this.
I already asked a similar question about this here which did solve the first part of my problem now I have another. I want the Ctrl + N to launch a script that contains an AJAX but once I run the .get function it cause the default to launch. Does anyone know a work around for this.
This fiddle has some code that shows my problem. Here is some of the code.
function checkkey(e)
{
if(e.ctrlKey && e.keyCode == 'N'.charCodeAt(0) && !e.shiftKey && !e.altKey)
{
try{e.preventDefault();}catch(ex){}
var m_objXMLHttpReqObj = new XMLHttpRequest();
m_objXMLHttpReqObj.open("GET", "", false);
m_objXMLHttpReqObj.send();
}
}
JSFIDDLE
Your code was not preventing the default behavior
function checkkey(e) {
if(e.ctrlKey && e.keyCode == 'N'.charCodeAt(0) && !e.shiftKey && !e.altKey) {
e.preventDefault();
// Now send your AJAX
It also seems that AJAX is interfering with the ability to stop the default behavior. You were trying to send a synchronous AJAX request (don't ever do that, it will halt the browser) and you weren't giving it a URL to go to (triggering an error). As soon as you change your settings to properly give it a URL and to make it asynchronous, then it does work in FF.
Here's the working code
function checkkey(e) {
if(e.ctrlKey && e.keyCode == 'N'.charCodeAt(0) && !e.shiftKey && !e.altKey){
e.preventDefault();
var m_objXMLHttpReqObj = new XMLHttpRequest();
m_objXMLHttpReqObj.open("GET",
// URL to go to
"/echo/html/",
// Asynchronous
true);
m_objXMLHttpReqObj.send("");
}
}
However, in Chrome (it may not be of use to you, but to others who read this answer), if you add a console.log at the top of your handler, you'll see that the handler never gets. Therefore, Chrome doesn't even let you see the CTRL+N combination and you can't do anything about it. Just like Windows applications don't get notified of CTRL+ALT+DEL
If the application has to work for multiple browsers, my suggestion is to use a different combination like ALT+SHIFT+N, you really don't want to take over the basic browser shortcuts.
I believe your issue is that you are checking for a keypress and performing your action too late after the keyup. If you change your code to bind to the keydown of Ctrl+N I think your would be able to get the desired result. Something like:
var pKey
$(function() {
$(window).keydown(function(e) {
if(e.which == 17) {
pKey = e.keyCode;
}
else {
if(pKey == 17 && e.keyCode == 78) {
e.preventDefault();
console.log(e);
}
}
});
});
I added the global variable to capture the Ctrl key down which is keycode 17. I then capture the keycode 78 on the second keydown which is the N. Prior e.preventDefault() was not enough to prevent the new window so I had to add the extra lines for e.stopPropagation(), e.stopImmediatePropagation() and the console.log(e) can be removed. As Juan M has mentioned the others are no longer needed so I have updated the code to not include them.
Note: Firefox made a change in key biding priority. It use to be System>Website>Firefox however it seems people were complaining about websites that hijacked short cuts so the priority has changed to be System>Firefox>Website which means even if your website binds Ctrl+N the priority of Firefox for a new windows takes over.

How to override Backspace key function in document as in Google

Friends I was making a calculator like project so It is a full webpage that displays my calculator. For inputs from keyboard all other keys worked. And I also want to use backspace key to do [del] command as in calculator. But it always goes to Backward visited site. Here's my code:
$(document).keypress(function(e){
var e=window.event || e
var keyunicode=e.charCode || e.keyCode
if(keyunicode>=40 && keyunicode<=57 && keyunicode!=44)
{
//call a function [worked]
}
else if(keyunicode==61)
{
// call another function worked.
}
else if(keyunicode==8)
{
e.preventDefault();
delete_last();
return false;
}
});
Please help. I tried in chrome..
You should use a keydown listener to catch backspace. keypress is meant for character keys. keydown is useful for functional keys.
$(document).keydown(function (e) {
if (e.which === 8) {
//your custom action here
return false;
}
});
Chrome does only support the keypress event for some keys and backspace is not among these. See http://code.google.com/p/chromium/issues/detail?id=2606 for details.
React to keydown and call preventDefault on the event to see an effect in Chrome, too.

Is there a way to detect find on the page searches in javascript

each browser has find on page functionality (ctrl+F). Is there a way to detect user searches in javascript so that I could attach additional actions.
Here is a solution which can account for alternative page find situations (ex. Command+F, '/' on Firefox). It checks for any of these keypresses and sets a timer when they occur. If the window is blurred soon after, then it is assumed that the Find dialog is showing.
Disadvantages: does not account for the "Find" dialog being launched via the menu. I don't see any way to be sure about this part, since (as far as I know, at least) browser UI is off-limits to Javascript running inside the DOM.
var keydown = null;
$(window).keydown(function(e) {
if ( ( e.keyCode == 70 && ( e.ctrlKey || e.metaKey ) ) ||
( e.keyCode == 191 ) ) {
keydown = new Date().getTime();
}
return true;
}).blur(function() {
if ( keydown !== null ) {
var delta = new Date().getTime() - keydown;
if ( delta >= 0 && delta < 1000 )
console.log('finding');
keydown = null;
}
});
jsFiddle, tested in Chrome, Safari and Firefox
You could do (to detect whenb a user press ctrl+f):
window.onkeydown = function(e){
if(e.keyCode == 70 && e.ctrlKey){
//user pressed ctrl+f
}
Fiddle here: http://jsfiddle.net/d8T72/
Of course you can try to hook into ctrl+f or cmd+f shortcut, but even if that works on "some" browsers, that way you only would know that an user pressed that shortcut and is most likely to search for something.
If the browser allows to overwrite that shortcut, you could further block the default behavior and implement your own search logic on the site. But that is considered most times as very bad practice. Overwritting native browser behavior is pretty pretty bad.
On the other hand, there is no "event" which gets triggered when a browser executed a search process. In short words, no, there actually is no way to detect or hook into a search process with javascript (if there is one, it's never gonna be cross browser compatible).
As initially suggested by #Nicola Peluchetti, here is a slightly improved version by feature sniffing:
window.onkeydown = function(e){
var ck = e.keyCode ? e.keyCode : e.which;
if(e.ctrlKey && ck == 70){
alert('Searching...');
}
}
Browser search test case »

Categories