Делегирование событий / Присоединение событий к динамически создаваемым элементам с использованием Vanilla JavaScript - PullRequest
0 голосов
/ 23 апреля 2020

Я в процессе преобразования большого скрипта из jQuery в JavaScript. Это был код, который я сам не написал, но который я забыл из проекта на GitHub.

Я ознакомился с W3Schools, официальной документацией и этим сайтом в качестве справочного материала.

http://youmightnotneedjquery.com/

Одна из частей, которую я пытаюсь преобразовать в JavaScript, следующая:

$('body').on('click','.vb',function(){
    exportVB(this.value);
});

Согласно вышеупомянутой ссылке,

$(document).on(eventName, elementSelector, handler);

преобразуется в это

document.addEventListener(eventName, function(e) {
    // loop parent nodes from the target to the delegation node
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches(elementSelector)) {
            handler.call(target, e);
            break;
        }
    }
}, false);

Моя попытка заключается в следующем

/*document.addEventListener('click',function(e) {
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches('.vb')) {
            exportVB.call(target,e);
            break;
        }
    }
}, false);*/

Это, очевидно, не сработало, поэтому я сделал поиск в Google, который привел меня к этому решению StackOverflow

Присоединение события к динамическим c элементам в javascript

document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });

//$(document).on('click','#btnPrepend',function(){//do something})

Тестирование, которое дало мне эту идею. Я закомментировал это, потому что это, очевидно, тоже не сработало.

/*document.addEventListener('click',function(e) {
    if (e.target && e.target.className == 'vb') {
        exportVB(this.value);
    }
});*/

Просто для справки, оригинальная функция jQuery работает хорошо.

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Вместо того, чтобы вручную перебирать каждый родительский элемент, рассмотрите возможность использования .closest вместо него, который вернет элемент-предок ( или текущий элемент), который соответствует селектору:

document.querySelector('button').addEventListener('click', () => {
  document.body.insertAdjacentHTML('beforeend', '<span class="vb">some span </span>');
});

document.body.addEventListener('click', (e) => {
  if (e.target.closest('.vb')) {
    console.log('vb clicked');
  }
});
<button>add span</button>
0 голосов
/ 23 апреля 2020

Я решил это.

document.body.addEventListener('click',function(e) {
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches('.vb')) {
            exportVB(target.value);
            break;
        }
    }
});

Я не могу объяснить, как это работает, потому что я изначально не писал оригинальный код. Но я изменил две вещи:

  • exportVB.call(target.e) на exportVB(target.value)
  • Удаление false в качестве последнего аргумента.
...