Why does addEventListener fire before the event if at all? [duplicate]

喜欢而已 提交于 2019-12-18 04:52:48

问题


I was experimenting [in jsfiddle] w/a function created to append a newly created TextNode to the <p> in the HTML below:

    <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>

Here is my javascript as well:

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

        p1.appendChild(newtext);
    }

This works fine. However, the crux reveals itself when I attempt to make my javascript 'unobtrusive' by removing the behavior from the markup...

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

then utilizing a loop to attach addEventListener to each <button> element, which in turn uses the child TextNode to call 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));
    }

Two strange things happen with my code:
When [jsfiddle's] Code Wrap is set to 'no wrap - in head', nothing happens.

However, When Code Wrap is set to 'onLoad', 'onDomReady' or 'no wrap - in body' the function runs before the click and I get this.

Could someone tell me what I'm missing?


回答1:


The root of your problem is here:

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

You're executing the function rather than passing it to the event listener. Instead, pass the function by reference, then get the innerHTML inside the function.

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/




回答2:


First, your usage of Add Event listener is wrong. add event listener is expecting a function reference in the second parameter not a function call.

The following is a function reference:

var myfunctionreference = addTextNode;

This is a function call and will execute the function

var myfunctioncall = addTextNode();

In your code you are actually calling the function to use as the event handler instead of referencing it. Here is some Reference for .addEventListener()

You should be binding the event like this:

button.addEventListener("click", addTextNode);

Second, the event knows the element and knows the event. Your function call should be created to accept the event and not an arbitrary string. Then utilizing the event or "this" will allow you to get your hands on the text your looking for.

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

    p1.appendChild(newtext);
}


来源:https://stackoverflow.com/questions/23815294/why-does-addeventlistener-fire-before-the-event-if-at-all

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