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.
Related
I'm building an SPA where it would be quite useful if I could capture the shortcuts cmd/ctrl+shift+1 through 9. It appears to me that this should be possible, since no browser I know binds these keys to anything else, but for some reason, pressing cmd+shift+1 (I'm using a macbook) fails to even cause a keyboard event.
Is this an inherent limitation of Chrome, or is there some special thing that I don't know of that needs to be done to capture these events?
I don't have a macbook, but I can capture ctrl+shift+1 (be sure to give focus to the snippet results frame):
document.body.addEventListener('keyup', function(e)
{
if((e.code == 'Digit1' || e.code == 'Numpad1') && e.ctrlKey && e.shiftKey)
{
console.log('ctrl+shift+1');
}
else
{
console.log(e.key, 'pressed')
}
});
This is layout dependent, i.e. if you are not using QWERTY, beware! See the KeyboardEvent page for help with different keyboard layouts.
Rather vague title, I know, but I'm binding a custom key event to the document object to catch AltR combination keypresses, like this:
document.body.onkeydown = function(event){
event = event || window.event;
var keycode = event.charCode || event.keyCode;
if (keycode === 82) {
if (event.altKey) {
if (!canReload) {
canReload = true;
window.location.href += "#doGreaseRefresh";
} else {
canReload = false;
window.location.href = window.location.href.replace("#doGreaseRefresh", "");
}
return false;
}
}
}
The code runs as expected but also produces a rather annoying "beep" sound as well. How can I prevent this? return false didn't prove to be the answer, so I'm wondering if it's even possible.
Oh, and if you're wondering, this is in a Chrome userscript (Content script) to refresh Stack Overflow's home page every 10 seconds if I've pressed AltR, and to stop refreshing once I've pressed AltR again. :)
Not being able to stop the beep is apparently a bug in Chrome: http://code.google.com/p/chromium/issues/detail?id=105500. return false works in Firefox without a beep.
Cheers-
As ZachB points out, this appears to be a bug with Chrome.
To work around this annoyance:
Go into the Windows control panel.
Select Sounds or System Sounds
Assign (None) for the sound of the Default Beep.
(I like to do this anyway, since it's 50 times more annoying than it is useful).
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 ยป
My company uses Confluence for its internal wiki, which is fine, except that the editor has some keyboard shortcuts bound that drive me up the wall. In particular, it uses ^K for "insert link", when I want it to honor the system default behavior of "kill line".
I've tracked down the relevant code that inserts the listener:
$("#markupTextarea").select(function () {
AJS.Editor.storeTextareaBits(true);
}).keyup(function (e) {
AJS.Editor.contentChangeHandler();
if (e.ctrlKey) {
if (e.keyCode == 75) {// bind ctrl+k to insert link
return openLinkPopup(e);
}
if (e.keyCode == 77) {// bind ctrl+m to insert image
$("#editor-insert-image").click();
return false;
}
}
}).keydown(function (e) {
// prevent firefox's default behaviour
if (e.ctrlKey && e.keyCode == 75) {
return AJS.stopEvent(e);
}
}).change(function () {
AJS.Editor.contentChangeHandler();
});
For context, it seems like they're using a customized version of TinyMCE. Ideally, I'd like a userscript for Chrome that nukes these event listeners, but I can't even get them to go away by doing things to them in the Chrome JS console.
Things I've tried (mostly at other people's suggestion; I'm not exactly a stellar JS hacker):
$('markupTextarea').unbind('select') -- says Object #<HTMLTextAreaElement> has no method 'unbind'
$('markupTextarea').removeEventListener -- doesn't work since I don't have a name to reference these listeners by
I'm pretty much out of ideas.
Your $ isn't jQuery.
Write jQuery('#markupTextarea').unbind('select').
As the default behavior of IE is to switch to the full screen mode on Alt-Enter command. I've to avoid this and have to attach a custom behavior.
Is it doable?
Not in JavaScript, no.
This is a behaviour of the application, which you don't really have control over (aside from browser extensions, and such).
You could try catching the key presses on your page, but it wouldn't prevent the user from easily circumventing it.
See http://www.webonweboff.com/tips/js/event_key_codes.aspx for a list of the character codes for keys. I'm pretty sure it's not reliable for catching combinations of key presses.
Besides, Alt+Enter in IE results in an expected behaviour and you should not try to override this via a webpage.
Since you can't beat 'em, join 'em. Meaning, since you can catch the event but can't stop it, how about you just run the same command in a timeout after the user presses alt+enter?
Example:
<script type="text/javascript">
document.onkeydown = handleHotKeys;
function handleHotKeys(e) {
var keynum = getKeyCode(e);
var e = e || window.event;
if (keynum==13 && e.altKey) { // handle enter+alt
setTimeout("toggleFullscreenMode",100);
}
}
function getKeyCode(e){
if (!e) { // IE
e=window.event;
return e.keyCode;
} else { // Netscape/Firefox/Opera
return e.which;
}
}
function toggleFullscreenMode() {
var obj = new ActiveXObject("Wscript.shell");
obj.SendKeys("{F11}");
}
</script>
DISCLAIMER: Tested in IE8. You will have to look at the browser and version to get this to work for the specific version of the browser you are targeting. This also assumes that the user will have javascript and activex objects enabled.