Почему addEventListener срабатывает до события, если вообще срабатывает? [дубликат]


На этот вопрос уже есть ответ здесь:

Я экспериментировал [в jsfiddle] с функцией, созданной для добавления вновь созданного TextNode к <p> в HTML ниже:

    <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);
    }

Это прекрасно работает. Тем не менее, crux раскрывается, когда я пытаюсь сделать свой 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] Code Wrap установлен в "no wrap - in head", ничего не происходит.

Однако, когда обернуть код имеет значение 'события onload', 'onDomReady" или " нет обруча - в body ' функция запускается до щелчка, и я получаю это .

Может ли кто-нибудь сказать мне, чего мне не хватает?
2 6

2 ответа:

Корень вашей проблемы здесь:

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/

Во-первых, вы неправильно используете прослушиватель событий Add. добавить прослушиватель событий ожидает ссылка на функцию в качестве второго параметра не вызов функции.

Ниже приводится ссылка на функцию:

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);
}