【问题标题】:Why does addEventListener fire before the event if at all? [duplicate]如果有的话,为什么 addEventListener 在事件之前触发? [复制]
【发布时间】:2014-05-22 19:09:58
【问题描述】:

我正在 [在 jsfiddle 中] 尝试使用创建的函数将新创建的 TextNode 附加到下面 HTML 中的 <p>

    <button onclick="addTextNode('YES! ');">YES!</button>
    <button onclick="addTextNode('NO! ');">NO!</button>
    <button onclick="addTextNode('WE CAN! ');">WE CAN!</button>
    <hr />
    <p id="p1">First line of paragraph.</p>

这也是我的 javascript:

    function addTextNode(text) {
        var newtext = document.createTextNode(text),
            p1 = document.getElementById("p1");

        p1.appendChild(newtext);
    }

这很好用。但是,当我尝试通过从标记中删除行为来使我的 javascript“不显眼”时,症结就会显现出来......

    <button>YES!</button>
    <button>NO!</button>
    <button>WE CAN!</button>
    <hr />
    <p id="p1">First line of paragraph.</p>

然后使用循环将addEventListener 附加到每个&lt;button&gt; 元素,然后使用子TextNode 调用addTextNode

    function addTextNode(text) {
        var newtext = document.createTextNode(text),
            p1 = document.getElementById("p1");

        p1.appendChild(newtext);
    }

    var btns = document.getElementsByTagName("button");

    for(i = 0; i < btns.length; i++){
        var button = btns[i]; 
        button.addEventListener("click", addTextNode(button.innerHTML));
    }

我的代码发生了两件奇怪的事情:
当 [jsfiddle's] Code Wrap 设置为 'no wrap - in head' 时,什么也没有发生。

但是,当 Code Wrap 设置为 'onLoad'、'onDomReady' 或 'no wrap - in body' 时,函数会在点击之前运行,我会得到 this

谁能告诉我我错过了什么?

【问题讨论】:

    标签: javascript for-loop event-handling addeventlistener


    【解决方案1】:

    问题的根源在这里:

    button.addEventListener("click", addTextNode(button.innerHTML))
    

    您正在执行该函数,而不是将其传递给事件侦听器。相反,通过引用传递函数,然后获取函数内部的 innerHTML。

    function addTextNode() {
        var newtext = document.createTextNode(this.innerHTML),
            p1 = document.getElementById("p1");
    
        p1.appendChild(newtext);
    }
    
    var btns = document.getElementsByTagName("button");
    
    for(i = 0; i < btns.length; i++){
        var button = btns[i]; 
        button.addEventListener("click", addTextNode);
    }
    

    http://jsfiddle.net/bn85J/

    【讨论】:

    • 我接受了您的简洁回答。感谢您的澄清。
    • 重复问题的答案建议:button.addEventListener("click", function(){ addTextNode(button.innerHTML)}).
    • @alexkovelsky 和?他们都工作。
    • @KevinB - 我的评论表明可以使用参数调用处理程序。这是一个很大的区别。
    • @alexkovelsky 好吧,不,您的处理程序是function () {}。然后调用另一个函数
    【解决方案2】:

    首先,您对 Add Event listener 的使用是错误的。添加事件侦听器期望第二个参数中的函数引用而不是函数调用。

    以下是函数参考:

    var myfunctionreference = addTextNode;
    

    这是一个函数调用,将执行该函数

    var myfunctioncall = addTextNode();
    

    在您的代码中,您实际上是在调用函数以用作事件处理程序,而不是引用它。 这是.addEventListener()的一些参考

    你应该像这样绑定事件:

    button.addEventListener("click", addTextNode);
    

    第二,事件知道元素,知道事件。应该创建您的函数调用以接受事件而不是任意字符串。然后利用事件或“this”将让您获得您正在寻找的文本。

    function addTextNode(evt) {
        var newtext = document.createTextNode(this.innerHTML),
            p1 = document.getElementById("p1");
    
        p1.appendChild(newtext);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-07
      • 2016-12-11
      • 1970-01-01
      • 2016-01-19
      • 2015-07-04
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      相关资源
      最近更新 更多