5

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

Community
  • 1
  • 1
wolfcall
  • 678
  • 1
  • 8
  • 18

2 Answers2

5

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.

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
1

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.

AxGryndr
  • 2,274
  • 2
  • 22
  • 45
  • I just tried that here [Fiddle](http://jsfiddle.net/wolfcall/rSQaM/1/) is doesn't work once I added AJAX. Thanks for trying. – wolfcall Apr 15 '13 at 17:54
  • I went round on this for a while and I think that I have something that works. I have updated the code. Fiddle does not seem to recognize this but when I added it to a quick HTML page I made in Notepad Firefox did not open a new tab when I hit Ctrl+T. – AxGryndr Apr 15 '13 at 19:07
  • However since you are trying to prevent only one Ctrl event it may need a little work still. – AxGryndr Apr 15 '13 at 19:13
  • you said you had something that might work. Could you send it to me? I would like to see it. – wolfcall Apr 16 '13 at 12:46
  • 1
    The code I edited will prevent all keypress events. I was reading the .keypress does not always respond to CTRL, ALT, SHIFT etc so I tried .keydown with the same result. I then found out that 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. Do you have to override Ctrl+N? – AxGryndr Apr 16 '13 at 16:43
  • Hmmm... I think I will have to resort to the backup plan. That bit of knowledge does help I think I will make it where another key is involved. Thanks for your help the priority information is very interesting. I will have to rethink how I will work this short cut. Thanks a lot. – wolfcall Apr 16 '13 at 16:56
  • I got it! I will edit the code. It will block Ctrl+N but still allow others like Ctrl+T. – AxGryndr Apr 16 '13 at 17:02
  • -1 so that others don't follow the practice you posted in your answer. You used a sledgehammer to crack a nut (and potentially broke the table). You should understand what `stopPropagation, stopImmediatePropagation, preventDefault` do. `stopPropagation()` prevents handlers at parents from being called, don't need this. `stopImmediatePropagation()` prevents handlers at the same element from being called (and parents), don't need this. `preventDefault()` prevents the default browser action, like stopping the browser from following a link, this is all you need, no more. See my answer. – Ruan Mendes Apr 19 '13 at 18:03
  • Prior to capturing the Ctrl keypress separate of the N it was not enough to just use the preventDefault(). I did not test my script after to see if the others could be removed. I have done so and you are correct. I will update my code. – AxGryndr Apr 19 '13 at 19:38
  • I just want to say love the sledgehammer metaphor. Thanks for the laugh. – wolfcall Apr 22 '13 at 16:58