2016-02-18 72 views
0

考虑这个片断:优先级嵌套事件

<div onkeypress="console.log('parent');"> 
    <input type="text" onkeypress="console.log('child');"> 
</div> 

两个嵌套的元素都与一个onkeypress事件-event。当我将光标放在输入的结果中并敲击键盘上的某个键时,我得到

child 
parent 

以该顺序记录到控制台。我的问题是,如果我能指望它总是按照这个顺序开火。即最内层的元素总是会先发射?

+2

这是事件冒泡的一个很好的解释,你可以期望什么/控制:HTTP ://www.quirksmode.org/js/events_order.html也阅读此:http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-pturing –

回答

1

是的,你可以像注意到MDNW3你可以在最内侧的事件计数火灾第一,作为动作冒泡,随后发生的事件将触发。浏览器认为按键事件有所不同。

QuirksMode:(从外部向内部捕捉火焰,例如向下箭头和从内部冒泡到外部,即向上箭头)。

 Capturing-> | |/\ <-Bubbling 
-----------------| |--| |----------------- 
| element1  | | | |    | 
| -------------| |--| |-----------  | 
| |element2 \/| |   |  | 
| --------------------------------  | 
|  W3C event model     | 
------------------------------------------ 

使用事件侦听器,您可以指定捕获vs冒泡与第三个参数。

element1.addEventListener('keypress',myScript,true) // Capture element1.addEventListener('keypress',myScript,false) // Bubble*default

object.addEventListener("keypress", myScript, false); == <div onkeypress="myScript()">

有一点需要注意,IE不遵循相同的模式,但你仍然可以依靠冒泡,即内而外。

+0

好主意@swelet –

0

这取决于浏览器。但是,您可以通过在元素上放置addEventListener()来决定执行顺序。

本指南解释了它在走向深沉: http://www.quirksmode.org/js/events_order.html

+0

*“这取决于浏览器。 “* 怎么会这样?你能详细说明吗? –

+0

现在,在所有的浏览器中,首先捕获并且冒泡事件。没有addEventListener()就会忽略捕获,将其设置为true。 但它不会为IE浏览器<9工作。所以他不应该依靠默认行为。 – jozhe

+0

那么,旧版浏览器不支持捕获的事实并不意味着冒泡在每个浏览器中都不起作用:) –

1

是的。无论你是在html中添加事件处理程序(如你的例子)还是在js文件中。无论您在JavaScript文件中注册事件处理程序的顺序如何,正如Rob & Vinny所解释的那样,事件会从元素中“冒泡”。按键事件从dom元素输入开始,然后冒泡到他的父母,以及他父母的父母,等等。因此,事件处理程序将以相同的顺序触发。

这就是你需要知道的一切吗? 如果您对这两个独立的处理程序有特定的用例,那么您可以解释它是什么,并且我可以尝试编写解决方案,因为在您的示例中,我无法看到如何在同一事件上执行两个操作相同的元素。

编辑:那么为什么不使用文档的全局侦听器与检查如果焦点上的元素是输入?

Example on JSFiddle

document.addEventListener('keypress', function(e){ 
    var key = String.fromCharCode(e.which), 
     targetElt = e.target; 

    if (key === 'a'){ 
    console.log('-- Action when "a" is pressed') 
    if (targetElt.nodeName === 'INPUT') { 
     console.log('-- Action when "a" is pressed and the focus is on an input'); 
    } 
    } 
}, false); 

如果按 'A' 仅第一console.log被调用时,如果按 'A' 时,input集中,既console.log被调用。

如果您有多个按键,我会建议使用switch语句,而不是if/else if/else

感谢

+0

好的谢谢。这是一个虚拟的例子,我实际上在React中工作,而问题源于想要拥有一些全局键盘shorctut,其中一些具有增加的行为,如果特定的元素聚焦。 Vinny还表示冒泡是这种方式的标准行为。 – swelet

+0

我用一个例子编辑了我的答案。这是你所期望的吗? – OxyDesign