My requirement is just easy: user press Ctrl key some notification appear on my page, and when released the notifications just disappear, so i need to track modifier keys such as Ctrl. Unfortunately i google and didn't find any clues, some famous keyboard libs such as Mousetrap and keymaster seem also does not cover this topic.
Any ideas?
Modifier keys trigger keydown (but not keypress). Then you can simply check the flags defined on the event object. shiftKey, altKey, ctrlKey, metaKey, etc.
A full list is here: http://api.jquery.com/category/events/event-object/
With jQuery, you can just use the keydown and keyup event handlers and you will see the Ctrl key go down and up. If you want to keep track of whether it's down or up, then just set a global flag when it goes down and clear the flag when it goes up.
Example code:
$(document).keydown(function(e) {
if (e.which == 17) {
$("#result").append("ctrl key pressed<br>");
}
});
JQuery doc on e.which: http://api.jquery.com/event.which/
Working demo: http://jsfiddle.net/jfriend00/mezwF/
Try this-
var ctrlKey = false;
window.onkeydown = function(e) {
if(e.keyCode == 17) {
ctrlKey = true;
}
};
window.onkeyup = function(e) {
if(e.keyCode == 17) {
ctrlKey = false;
}
};
function notify() {
if(ctrlKey) {
$('#notification').show();
} else {
$('#notification').hide();
}
}
function main() {
var _inter = setInterval(notify, 100);
}
main();
Related
How do I go about capturing the CTRL + S event in a webpage?
I do not wish to use jQuery or any other special library.
Thanks for your help in advance.
An up to date answer in 2020.
Since the Keyboard event object has been changed lately, and many of its old properties are now deprecated, here's a modernized code:
document.addEventListener('keydown', e => {
if (e.ctrlKey && e.key === 's') {
// Prevent the Save dialog to open
e.preventDefault();
// Place your code here
console.log('CTRL + S');
}
});
Notice the new key property, which contains the information about the stroked key. Additionally, some browsers might not allow code to override the system shortcuts.
If you're just using native / vanilla JavaScript, this should achieve the results you are after:
var isCtrl = false;
document.onkeyup=function(e){
if(e.keyCode == 17) isCtrl=false;
}
document.onkeydown=function(e){
if(e.keyCode == 17) isCtrl=true;
if(e.keyCode == 83 && isCtrl == true) {
//run code for CTRL+S -- ie, save!
return false;
}
}
What's happening?
The onkeydown method checks to see if it is the CTRL key being pressed (key code 17).
If so, we set the isCtrl value to true to mark it as being activated and in use. We can revert this value back to false within the onkeyup function.
We then look to see if any other keys are being pressed in conjunction with the ctrl key. In this example, key code 83 is for the S key. You can add your custom processing / data manipulation / save methods within this function, and we return false to try to stop the browser from acting on the CTRL-S key presses itself.
document.onkeydown = function(e) {
if (e.ctrlKey && e.keyCode === 83) {
alert('hello there');
// your code here
return false;
}
};
You need to replace document with your actual input field.
DEMO
document.onkeydown = function(e) {
if (e.ctrlKey && e.keyCode === 83) {
alert('strg+s');
}
return false;
};
Some events can't be captured, since they are capture by the system or application.
Oops you wanted simultaneous, changed code to reflect your scenario
function iskeyPress(e) {
e.preventDefault();
if (e.ctrlKey&&e.keyCode == 83) {
alert("Combination pressed");
}
return false;//To prevent default behaviour
}
Add this to body
<body onkeyup="iskeypress()">
Mousetrap is a great library to do this (8,000+ stars on Github).
Documentation: https://craig.is/killing/mice
// map multiple combinations to the same callback
Mousetrap.bind(['command+s', 'ctrl+s'], function() {
console.log('command s or control s');
// return false to prevent default browser behavior
// and stop event from bubbling
return false;
});
Add Shortcuts JS library and do the following code :
<script src="js/libs/shortcut/shortcut.js" type="text/javascript"></script>
Then
shortcut.add("Ctrl+S", function() {
alert("لقد قمت بالصغط على مراقبة مع حرف السين");
});
I would like to know what key was downed (held and pressed) while a double click event was fired on an element.
The event handler allows me to get alt, shift, meta and ctrl key. What if I want to detect whether 'x' was downed when a double click was made... Or any other letter or number for that matter.
If you want to detect ctrl, alt or shift keys, they are exposed on the event object that is passed to you.
$(document).on('dblclick', function(e){
/*
* here you could use e.altKey, e.ctrlKey and e.shiftKey - all of them
* are bools indicating if the key was pressed during the event.
*/
});
If you want to detect a different key, then omar-ali's answer seems to be the right thing to do.
You must store the keycode until the keyup event, and reference the current value at the time of the double-click event.
var heldKey;
$(document).on({
'keydown' : function(e) {
heldKey = e.which || e.keyCode;
},
'keyup': function(e) {
heldKey = undefined;
},
'dblclick': function(e){
console.log(String.fromCharCode(heldKey));
}
});
One possibility is to do this, 88 = the letter x.. but.. is there a better way.
$(document).on('keydown','body',function(e) {
//console.log(e.keyCode);
if(e.keyCode==88)
keyed = true;
});
$(document).on('keyup','body',function(e) {
if(e.keyCode==88)
keyed = false;
});
$(document).on('dblclick','body',function(e) {
if(keyed==true)
alert('yes');
keyed=false;
});
I have a text input, that presently goes transparent when a user presses shift (keydown) and binds a listener for the shift key going up
ie.
$('#foo').keydown(function(){
if(event.which==16){
//make #foo transparent
$(this).keyup(function(){
if(event.which==16){
//return #foo to its former glory
$(this).unbind('keyup');
}
});
};
})
This works fine when no characters are pressed in the interim between depressing and releasing the shift key. The problem is that when shift is down and another character is pressed, the shift key seems to have been completely forgotten about. When the shift key is released, no keyup fires.
I tried triggering a 'fake' keydown with the .which property set to 16, to nudge it in the right direction after other characters are pressed, but to no avail.
Any suggestions would be greatly appreciated!
While pressing shift, it will continuously trigger keydown events until you release it, so your example will bind as many keyup handlers as there are keydown events triggered. This will most likely cause all kind of weird problems.
Instead, bind both keydown and keyup to the same handler and do your magic in there:
$("#foo").on("keydown keyup", function (e) {
if (e.which === 16) {
if (e.type === "keydown") {
// make #foo transparent
} else {
// return #foo to its former glory
}
}
});
See test case on jsFiddle.
However, if you lose focus of the input while pressing shift and then release, it will not work as expected. One way to solve it is to bind to window instead:
var $foo = $("#foo");
var shiftPressed = false;
$(window).on("keydown keyup", function (e) {
if (e.which === 16) {
shiftPressed = e.type === "keydown";
if (shiftPressed && e.target === $foo[0]) {
$foo.addClass("transparent");
} else {
$foo.removeClass("transparent");
}
}
});
$foo.on("focus blur", function (e) {
if (e.type === "focus" && shiftPressed) {
$foo.addClass("transparent");
} else {
$foo.removeClass("transparent");
}
});
See test case on jsFiddle.
On Mac browsers, javascript does not receive keyup events for most keys (other modifier keys seem to be an exception) when the metakey is down. Use this jsfiddle to demonstrate (focus the result area and try something like cmd + x, the x will not receive a keyup event):
http://jsfiddle.net/mUEaV/
I've reproduced this in stable releases for Chrome, FF, Safari and Opera. The same thing does not seem to happen with the control key in Windows 7.
Is the OS hijacking the keyup event? This seems especially strange since commands that use the metakey such as save, find, cut, copy, etcetera all activate on keydown not on keyup, and can be hijacked by the javascript just fine.
It's simply not possible to get the onKeyUp events when meta is used, I learned today. Very unfortunate and difficult to work around. You'll have to emulate them some other way.
Edit: To clarify, this is only on Mac and occurs due to OS level handling of the event. It cannot be overridden. Sorry to be the bearer of bad news.
Although event.metaKey returns false, event.keyCode and event.key are still populated.
document.addEventListener('keyup', function(e) {
console.log(e.metaKey || e.key);
});
Click here then press the Command, Control, or Option keys.
Is the browser window retaining the focus when you press those keys? In windows you can get similar result when pressing windows+R or CTRL+ESC and similar key combinations that make browser to loose focus and that results in missed events.
While keyup events are indeed not available when the meta key is pressed, you can still get keydown events for all keys, as well as keyup events for the meta key itself.
This allows us to just simply keep track of the state of the meta key ourselves, like so:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
By now additionally checking for the main key, plus cancelling the default behavior with Event.preventDefault() we can easily listen for key combinations (like here e.g. CMD+K) and prevent the browser from handling them:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
if (event.key == 'k' && metaKeyDown) {
event.preventDefault();
console.log('CMD+K pressed!');
}
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
(Note the observation of the k key taking place already on keydown.)
Also, please be aware that when used incorrectly, this can break standard browser functionality (e.g. like CMD+C or CMD+R), and lead to poor user experience.
You can create an artificial keyup event by waiting for a certain period after the last keydown event. The only caveat is people will have different repeat rates on their os.
https://jsfiddle.net/u7t43coz/10/
const metaKeyCodes = ["MetaLeft", "MetaRight"];
const shiftKeyCodes = ["ShiftLeft", "ShiftRight"];
const ctrlKeyCodes = ["ControlLeft", "ControlRight"];
const altKeyCodes = ["AltLeft", "AltRight"];
const modifierKeyCodes = [
...metaKeyCodes,
...shiftKeyCodes,
...ctrlKeyCodes,
...altKeyCodes
];
// record which keys are down
const downKeys = new Set()
const artificialKeyUpTimes = {}
function onKeydown(e) {
downKeys.add(e.code);
// do other keydown stuff here
console.log("meta", e.metaKey, e.code, "down")
// check if metaKey is down
if (metaKeyCodes.some(k => downKeys.has(k))) {
downKeys.forEach(dk => {
// we want to exclude modifier keys has they dont repeat
if (!modifierKeyCodes.includes(dk)) {
// fire artificial keyup on timeout
if (!artificialKeyUpTimes[dk])
setTimeout(
() => fireArtificialKeyUp(dk, e),
500
);
artificialKeyUpTimes[dk] = Date.now();
}
});
}
}
function fireArtificialKeyUp(code, e) {
// if enough time has passed fire keyup
if (Date.now() - artificialKeyUpTimes[code] > 100) {
delete artificialKeyUpTimes[code];
//if key is still down, fire keyup
if (downKeys.has(code)) {
const eCode = isNaN(code) ? { code: code } : { keyCode: code };
document.dispatchEvent(
new KeyboardEvent("keyup", { ...e, ...eCode })
);
}
} else {
setTimeout(() => fireArtificialKeyUp(code, e), 100);
}
}
function onKeyup(e) {
downKeys.delete(e.code);
// do keyup stuff here
console.log("meta", e.metaKey, e.code, "up")
}
document.addEventListener("keydown", onKeydown)
document.addEventListener("keyup", onKeyup)
How do I go about capturing the CTRL + S event in a webpage?
I do not wish to use jQuery or any other special library.
Thanks for your help in advance.
An up to date answer in 2020.
Since the Keyboard event object has been changed lately, and many of its old properties are now deprecated, here's a modernized code:
document.addEventListener('keydown', e => {
if (e.ctrlKey && e.key === 's') {
// Prevent the Save dialog to open
e.preventDefault();
// Place your code here
console.log('CTRL + S');
}
});
Notice the new key property, which contains the information about the stroked key. Additionally, some browsers might not allow code to override the system shortcuts.
If you're just using native / vanilla JavaScript, this should achieve the results you are after:
var isCtrl = false;
document.onkeyup=function(e){
if(e.keyCode == 17) isCtrl=false;
}
document.onkeydown=function(e){
if(e.keyCode == 17) isCtrl=true;
if(e.keyCode == 83 && isCtrl == true) {
//run code for CTRL+S -- ie, save!
return false;
}
}
What's happening?
The onkeydown method checks to see if it is the CTRL key being pressed (key code 17).
If so, we set the isCtrl value to true to mark it as being activated and in use. We can revert this value back to false within the onkeyup function.
We then look to see if any other keys are being pressed in conjunction with the ctrl key. In this example, key code 83 is for the S key. You can add your custom processing / data manipulation / save methods within this function, and we return false to try to stop the browser from acting on the CTRL-S key presses itself.
document.onkeydown = function(e) {
if (e.ctrlKey && e.keyCode === 83) {
alert('hello there');
// your code here
return false;
}
};
You need to replace document with your actual input field.
DEMO
document.onkeydown = function(e) {
if (e.ctrlKey && e.keyCode === 83) {
alert('strg+s');
}
return false;
};
Some events can't be captured, since they are capture by the system or application.
Oops you wanted simultaneous, changed code to reflect your scenario
function iskeyPress(e) {
e.preventDefault();
if (e.ctrlKey&&e.keyCode == 83) {
alert("Combination pressed");
}
return false;//To prevent default behaviour
}
Add this to body
<body onkeyup="iskeypress()">
Mousetrap is a great library to do this (8,000+ stars on Github).
Documentation: https://craig.is/killing/mice
// map multiple combinations to the same callback
Mousetrap.bind(['command+s', 'ctrl+s'], function() {
console.log('command s or control s');
// return false to prevent default browser behavior
// and stop event from bubbling
return false;
});
Add Shortcuts JS library and do the following code :
<script src="js/libs/shortcut/shortcut.js" type="text/javascript"></script>
Then
shortcut.add("Ctrl+S", function() {
alert("لقد قمت بالصغط على مراقبة مع حرف السين");
});