为什么click事件被触发两次?

时间:2014-11-19 16:43:26

标签: javascript html events addeventlistener

有人可以告诉我,为什么会为以下代码触发两次事件: http://jsfiddle.net/m8heyzgz/3/ 请打开你的控制台,firefox或chrome有控制台,然后观看结果 你单击'div1',然后 事件遍历序列将是:

  • DIV3
  • DIV2
  • DIV1
  • DIV3
  • DIV2
  • div1

据我所知,捕获阶段可以是从上到下,冒泡阶段可以是从目标到父节点。

我的问题为什么,它以相同的顺序被解雇了两次?

HTML:

<div id="div1">
    <div id="div2">
        <div id="div3">
            <form>
                <ul>
                    <li>
                        <label>                            
                            <div>
                                <div>div1</div>                            
                            </div>
                            <div>
                                <div>div2</div>                            
                            </div>
                            <div>                                  
                                <input type="checkbox" name="div3" value="div3" />
                            </div>
                        </label>
                    </li>
                </ul>
            </form>
        </div>
    </div>
</div>

JS:

var d1 = document.getElementById('div1');
var d2 = document.getElementById('div2');
var d3 = document.getElementById('div3');

var f = function(e) {
    console.log(e.currentTarget);
}

d1.addEventListener('click', f);
d2.addEventListener('click', f);
d3.addEventListener('click', f);

2 个答案:

答案 0 :(得分:5)

予。为什么订单相同?

2波&#39;顺序是一样的,因为你只看到两个事件的冒泡阶段,而不是捕获。如果你想看到捕获,你的addEventListener's third parameter(useCapture)应该是真的。

II。为什么要开2次?

  1. 当您点击标签的内容时,会从标签触发第一次点击事件。
  2. 第二次点击事件是通过合成点击
  3. 从标签的复选框中触发的。

    <强> 1。什么是合成点击?

    由程序代码启动的点击,而不是由输入设备启动。 (它fires a click event。)

    <强> 2。为什么合成点击会发生?

    因为这是the run synthetic click activation steps algorithm的第4步。

    <强> 3。为什么这个算法由浏览器运行?

    因为它尊重the W3C's recommendation

    &#34;标签元素的(...)激活行为(...)应与平台的标签行为相匹配&#34; &#34;例如,在单击复选框标签的平台上选中复选框,单击标签(...)可能会触发用户代理在输入元素上运行合成点击激活步骤,就好像元素本身已被触发一样由用户(...)&#34;

答案 1 :(得分:2)

请参阅HTML5规范:

“除非以下规则另有规定,否则标签元素没有标记控件......

... 如果未指定for属性,但label元素具有可变元素后代,则树序中的第一个此类后代是标签元素的标记控件。 ... < / p>

...例如,在单击复选框标签选中复选框的平台上,单击以下代码段中的标签可能会触发用户代理在输入元素上运行合成点击激活步骤,好像元素本身已被用户触发......“

http://www.w3.org/TR/html5/forms.html#labeled-control

因此,点击标签元素会在标签的第一个输入上触发合成点击事件 - 回答评论中的问题。