2

I'm trying to bind multiple functions to the document.onkeydown.

function keydownScreenHandler_1(event) {
  alert('- 1 -');
}
document.onkeydown=keydownScreenHandler_1;


function keydownScreenHandler_2(event) {
  alert('- 2 -');
}
document.onkeydown=keydownScreenHandler_2;

This of course just alerts - 2 - because the document.onkeydown gets overwritten by that second function.

Example (also on jsFiddle):

function keydownScreenHandler_1(event) {
  alert('- 1 -');
}
//Register the keydown event handler:
document.onkeydown=keydownScreenHandler_1;
    
    
function keydownScreenHandler_2(event) {
  alert('- 2 -');
}
//Register the keydown event handler:
document.onkeydown=keydownScreenHandler_2;
<h1>
  Click here to get focus, then press a key
</h1>

How can I get it to work so ondocument.onkeydown will alert both alerts?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
caramba
  • 21,963
  • 19
  • 86
  • 127
  • 1
    I was very surprised not to be able to find a clean duplicate of this question. I found several that involved this but with other bits thrown in, but this is the cleanest version of the question I've found. – T.J. Crowder Apr 13 '16 at 10:51

4 Answers4

4

Use modern event handling. On any half-decent up-to-date browser that's

document.addEventListener("keydown", keydownScreenHandler_1, false);
document.addEventListener("keydown", keydownScreenHandler_2, false);

On IE8 and earlier, or IE9-IE11 in their broken "compatibility" mode, it's:

document.attachEvent("onkeydown", keydownScreenHandler_1);
document.attachEvent("onkeydown", keydownScreenHandler_2);

There are other differences between attachEvent and addEventListener, such as where you get the event object from. If you need to support obsolete browsers like IE8 (or IE9-IE11 in (in)compatibility mode), this answer has a function to handle almost all the differences for you.

Updated snippet using addEventListener:

function keydownScreenHandler_1(event) {
  alert('- 1 -');
}
//Register the keydown event handler:
document.addEventListener("keydown", keydownScreenHandler_1, false);
    
function keydownScreenHandler_2(event) {
  alert('- 2 -');
}
//Register the keydown event handler:
document.addEventListener("keydown", keydownScreenHandler_2, false);
<h1>
  Click here to get focus, then press a key
</h1>

Updated snippet using hookEvent from the linked answer:

var hookEvent = (function() {
    var div;

    // The function we use on standard-compliant browsers
    function standardHookEvent(element, eventName, handler) {
        element.addEventListener(eventName, handler, false);
        return element;
    }

    // The function we use on browsers with the previous Microsoft-specific mechanism
    function oldIEHookEvent(element, eventName, handler) {
        element.attachEvent("on" + eventName, function(e) {
            e = e || window.event;
            e.preventDefault = oldIEPreventDefault;
            e.stopPropagation = oldIEStopPropagation;
            handler.call(element, e);
        });
        return element;
    }

    // Polyfill for preventDefault on old IE
    function oldIEPreventDefault() {
        this.returnValue = false;
    }

    // Polyfill for stopPropagation on old IE
    function oldIEStopPropagation() {
        this.cancelBubble = true;
    }

    // Return the appropriate function; we don't rely on document.body
    // here just in case someone wants to use this within the head
    div = document.createElement('div');
    if (div.addEventListener) {
        div = undefined;
        return standardHookEvent;
    }
    if (div.attachEvent) {
        div = undefined;
        return oldIEHookEvent;
    }
    throw "Neither modern event mechanism (addEventListener nor attachEvent) is supported by this browser.";
})();

function keydownScreenHandler_1(event) {
  alert('- 1 -');
}
//Register the keydown event handler:
hookEvent(document, "keydown", keydownScreenHandler_1, false);
    
function keydownScreenHandler_2(event) {
  alert('- 2 -');
}
//Register the keydown event handler:
hookEvent(document, "keydown", keydownScreenHandler_2, false);
<h1>
  Click here to get focus, then press a key
</h1>
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Call the required function from the other function as below. Updated fiddle

function keydownScreenHandler_1(event) {
  alert('- 1 -');
  keydownScreenHandler_2(event);
}

function keydownScreenHandler_2(event) {
  alert('- 2 -');
  keydownScreenHandler_3(event);
}

function keydownScreenHandler_3(event) {
  alert('- 3 -');
}

//Register the keydown event handler:
document.onkeydown = keydownScreenHandler_1;
<h1>
  Click here to get focus
</h1>
Pugazh
  • 9,453
  • 5
  • 33
  • 54
0
document.onkeydown = function() {
    keydownScreenHandler_1.apply(this, arguments);
    keydownScreenHandler_2.apply(this, arguments);
}

Or better addEventListener and attachEvent

Radek Pech
  • 3,032
  • 1
  • 24
  • 29
0
function keydownScreenHandler_1(event) {
  alert('- 1 -');
}

function keydownScreenHandler_2(event) {
  alert('- 2 -');
}

function keydownHandlers(event) {
  keydownScreenHandler_1(event);
  keydownScreenHandler_2(event);
}

document.addEventListener("keydown", keydownHandlers, false);

or you can add multiple calls of

document.addEventListener("keydown", function_name, false);

Try doing it this way...

Akash K.
  • 627
  • 1
  • 14
  • 27
  • That loses `this`. The OP's not using `this` in their example, but in the general case, `this` is an important thing for event handler functions. – T.J. Crowder Apr 13 '16 at 10:53
  • I answered it according to what the user asked... in case user wants to use `this` there is a second option as well... is that a good reason for downvote? – Akash K. Apr 13 '16 at 10:54
  • 1
    Don't assume you know who voted based on who commented. They're frequently different people. But in general, it's best not to provide significantly incomplete information to people asking basic questions, it just gives them something to trip over later. – T.J. Crowder Apr 13 '16 at 10:55
  • sorry my bad.. didn't mean it that way... :) just asked for your opinion... you're experienced user.. and reputation doesn't come free... – Akash K. Apr 13 '16 at 10:57