Why is tab keypress causing focus change also triggering keyup event?

跟風遠走 提交于 2019-12-08 09:35:16

问题


Pressing the tab key which triggers a focus change is also received by the input receiving the focus as a keyup.

a: <input type='text'/><br/>
b: <input type='text' onkeyup='alert("wtf?")'/><br/>

http://jsfiddle.net/59SnP/

As my control also uses tab (not in the example), I would want the focus related keyup event being consumed (but I want to receive other non-focus-change related tab events). I tried to research the rationale behind the current behavior but found nothing. The question: Where is this current behavior specified (event not consumed by focus change), and what would be a cross-browser workaround to force consuming it. Thx.


回答1:


You can try this. I changed your keyup event in your input :

<input type='text' onkeyup="if(!tabPressed){ alert('This is it !'); }"/>

And I added a little event handler which will raise a flag when the tab button is pressed :

var tabPressed = false;
document.addEventListener('keydown', function (e) {
    if(e.keyCode == 9) {
        tabPressed = true;   
    } else {
        tabPressed = false;
    }
}, false);



回答2:


Based on Nathan's insight, here is a fully working example:

// First part of Nathan's HACK (set a sentinel when a focus changing tab has happened)
var tabPressed = false;
// remove this listener to break the functionality
$(document).on("keydown", function (e) {
    if(e.keyCode == 9) {
        tabPressed = true;   
    } else {
        tabPressed = false;
    }
});

// The listener on the client input that would kill the keyup tab event upon focus change
$("#magic").on("keyup", function(e) {
    if (tabPressed && e.keyCode==9) {
        tabPressed = false; // reset the sentinel
        e.stopImmediatePropagation()
        e.preventDefault()
    }
})

And here is the second part, which is a simple skeleton of something meaningful. We disable TAB inside the input, and log it as we do with other keyups:

$("#magic").on("keydown", function(e) {
    if (e.keyCode==9) {
        e.preventDefault()
        e.stopPropagation()
    }
})

$("#magic").on("keyup", function(e) {
    $(this).val($(this).val() + " " + e.keyCode)
    e.stopPropagation()
    e.preventDefault()
})

The HTML backing the story is as simple as:

a: <input type='text'/><br/>
b: <input type='text'/><br/>
c: <input type='text' id='magic'/><br/>

If you want to play with it, here it is on jsfiddle

NOTE: This still is not the perfect solution, the sentinel is just reset inside the control, so if a tabpress moving the focus does not activate our input, the sentinel stucks, and the first event will be swallowed.. So here is an example of wrong behaviour:

  1. Click on input A
  2. Press TAB (focus moves to input B, tabPressed becomes true)
  3. Click on input C
  4. Press TAB (it is eaten up as sentinel is true)
  5. Press TAB (now it goes through)

Still it is slightly better to have to press TAB twice as to have something happening automatically, wo user control...



来源:https://stackoverflow.com/questions/22346903/why-is-tab-keypress-causing-focus-change-also-triggering-keyup-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!