Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Listenerы срабатывают сразу, не дожидаясь события, почему? (https://javascript.ru/forum/events/75096-listenery-srabatyvayut-srazu-ne-dozhidayas-sobytiya-pochemu.html)

__Alex__ 02.09.2018 15:14

Listenerы срабатывают сразу, не дожидаясь события, почему?
 
Добрый день, помогите разобраться. Listenerы срабатывают сразу, не дожидаясь события, почему?

Код:
<div id='1'>1: X</div>
<div id='2'>2: X</div>
<div id='3'>3: X</div>
<div id='out'></div>

<script>
    function out(id) {
        document.getElementById('out').innerHTML += (id + ' ');
    }

    function listener(id) {
        document.getElementById(id).addEventListener('click', out(id));
        /*
            а так работает корректно!!!:
            document.getElementById(id).addEventListener('click', function() {
            document.getElementById('out').innerHTML += (id + ' ');
        });
        */
    }

    listener(1);
    listener(2);
    listener(3);
</script>

Результат запуска:
1: X
2: X
3: X
1 2 3

Aetae 02.09.2018 17:21

https://javascript.ru/forum/misc/750...jj-knopki.html

__Alex__ 02.09.2018 19:19

Переделал по аналогии, ожидаемо заработало, т.к. по сути стало равным закомментированному куску.

<div id='1'>1: X</div>
<div id='2'>2: X</div>
<div id='3'>3: X</div>
<div id='out'></div>

<script>
    function out(id) {
        return function() {
            document.getElementById('out').innerHTML += (id + ' ');
        }
    }

    function listener(id) {
        document.getElementById(id).addEventListener('click', out(id));
        /*
                а так работает корректно!!!:
                    document.getElementById(id).addEventListener('click', function() {
                        document.getElementById('out').innerHTML += (id + ' ');
                    });
        */
    }

    listener(1);
    listener(2);
    listener(3);

</script>


Но осталось не понятно, почему работает именно так, почему не работает в первом случае? Подскажите, что почитать, чтобы разобраться в этом вопросе.

рони 02.09.2018 19:32

__Alex__,
потому-что в первом случае вы пишите
document.getElementById(id).addEventListener('clic k', undefined);

__Alex__ 02.09.2018 19:53

рони, неожиданно :) Думал, что листенер просто вызывает функцию при наступлении события... а ему оказывается нужно результат через замыкание вернуть...

Слегка прояснилось :write: , спасибо

__Alex__ 02.09.2018 19:57

Правда, осталось всё равно не понятно, почему функция вызывается до наступления события...

рони 02.09.2018 20:05

Цитата:

Сообщение от __Alex__
Думал, что листенер просто вызывает функцию при наступлении события

да именно так, но дайте функцию!!! а не результат функции.

Aetae 02.09.2018 20:18

__Alex__, медитируем на этот коммент до понимания.

Белый шум 02.09.2018 21:32

Цитата:

Сообщение от __Alex__
Правда, осталось всё равно не понятно, почему функция вызывается до наступления события...

out(id) - когда со скобками, то это сразу же вызовет ф-ию, в момент встречи в коде. Т.е. параметром, переданным в addEventListener будет результат выполнения данной ф-ии.

А если так - document.getElementById(id).addEventListener('clic k', out); - т.е. без скобок, то вы передаёте переменную out, которая содержит функцию. В этом случае она будет вызвана только при наступлении события 'click', но без параметров.

А вот так - document.getElementById(id).addEventListener('clic k', function() { out(id); }); - вы передали анонимную ф-ю, которой параметры и не нужны, но в момент своего вызова (при событии 'click') она выполнит out(id);

__Alex__ 03.09.2018 07:53

Белый шум, стало понятнее, спасибо.


Часовой пояс GMT +3, время: 06:48.