为什么addEventListener会在事件发生之前触发?

时间:2014-05-22 19:09:59

标签: javascript for-loop event-handling addeventlistener

我正在尝试[在jsfiddle] w /创建的函数,以便将新创建的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附加到每个<button>元素,然后使用子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&#39; s] Code Wrap设置为&#39;没有包装头时,没有任何反应。

但是,当Code Wrap设置为&#39; onLoad&#39;,&#39; onDomReady&#39;或者没有包裹身体&#39;该功能在点击之前运行,我得到this

有人能告诉我我错过了什么吗?

2 个答案:

答案 0 :(得分:10)

问题的根源在于:

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/

答案 1 :(得分:1)

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

以下是功能参考:

var myfunctionreference = addTextNode;

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

var myfunctioncall = addTextNode();

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

的参考资料

你应该绑定这样的事件:

button.addEventListener("click", addTextNode);

其次,事件知道元素并知道事件。应创建函数调用以接受事件而不是任意字符串。然后利用该事件或“此”将使您能够获得所需的文本。

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

    p1.appendChild(newtext);
}