Question

I have a webpage that has lots of 'windows', which aren't wrapped in iframes or anything silly. Each 'window' is its own 'App'.

One of these Apps has a ton DOM elements in it. I want to bind a listener to that App, which is encased in a DIV, and want to capture some hotkey presses such as the left and right arrows.

However, if some element that actually rightfully deserves focus (such as an input inside of this app) gets a left or right keypress, I want to ignore it.

Problems:

  • The above means I only want to capture keypress on DIVs, basically. I could add a tabindex, however the div isn't going to focus itself if someone clicks within that app, so i'm not sure what to do about that:

<div class='app-wrapper' tabindex='1'><!-- behold ye content --></div>

$('.app-wrapper').on('keypress', function(){
  // ... I dont think this will work.
});

  • I am not going to tell every single valid input / textarea in my app to stop propagating on a keypress.

Is there any good solution to achieving the above without a major hack job?

Was it helpful?

Solution

You could look at e.target in your listener function:

$('.app-wrapper').on('keypress', function(e){
    if(e.target.tagName === 'DIV'){ //Or, more jQuery-esque: $(e.target).is('div')
         console.log("Wooo, I'm totally a div. Let's do stuff");
    }
});

In that way you can ignore keypresses fired inside "valid" elements.

OTHER TIPS

Okay, I managed to figure it out.

My first complaint actually did end up working, and then coupled with $(element)[0].nodeName, it handled the latter complaint:

HTML

<div class='app-wrapper'><!-- behold ye content --></div>

JS

$('.app-wrapper').attr('tabindex', 1);

$('.app-wrapper').on('keypress', function(e){

  var nodeName = $(e.target)[0].nodeName;
  if (nodeName == 'INPUT' || nodeName == 'TEXTAREA') {

    // bug off...
    return;
  }

  // handle key press now.
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top