事件委派/使用Vanilla JavaScript将事件附加到动态创建的元素



我正在将一个大型脚本从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);*/

这显然不起作用,所以我在谷歌上搜索了一下,找到了这个StackOverflow解决方案

将事件附加到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函数运行良好。

我解决了它。

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作为最后一个参数

与其手动迭代每个父元素,不如考虑使用.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>

最新更新