我想弄清楚如何将事件绑定到动态创建的元素。即使在元素被销毁和重新生成后,我也需要该事件在元素上持续存在。
显然,使用 jQuery 的 live 函数很容易,但是使用原生 Javascript 实现它们会是什么样子?
我想弄清楚如何将事件绑定到动态创建的元素。即使在元素被销毁和重新生成后,我也需要该事件在元素上持续存在。
显然,使用 jQuery 的 live 函数很容易,但是使用原生 Javascript 实现它们会是什么样子?
这是一个简单的例子:
function live(eventType, elementId, cb) {
document.addEventListener(eventType, function (event) {
if (event.target.id === elementId) {
cb.call(event.target, event);
}
});
}
live("click", "test", function (event) {
alert(this.id);
});
基本思想是您希望将事件处理程序附加到文档并让事件在 DOM 中冒泡。然后,检查event.target
属性以查看它是否符合所需的条件(在这种情况下,只是id
元素的 )。
编辑:
@shabunc在我的解决方案中发现了一个相当大的问题——无法正确检测到子元素上的事件。解决此问题的一种方法是查看祖先元素以查看是否有指定的id
:
function live (eventType, elementId, cb) {
document.addEventListener(eventType, function (event) {
var el = event.target
, found;
while (el && !(found = el.id === elementId)) {
el = el.parentElement;
}
if (found) {
cb.call(el, event);
}
});
}
除了 Andrew 的帖子和 Binyamin 的评论之外,也许这是一个选项:
有了这个,您可以使用“nav .item a”作为选择器。基于安德鲁的代码。
function live (eventType, elementQuerySelector, cb) {
document.addEventListener(eventType, function (event) {
var qs = document.querySelectorAll(elementQuerySelector);
if (qs) {
var el = event.target, index = -1;
while (el && ((index = Array.prototype.indexOf.call(qs, el)) === -1)) {
el = el.parentElement;
}
if (index > -1) {
cb.call(el, event);
}
}
});
}
live('click', 'nav .aap a', function(event) { console.log(event); alert('clicked'); });
其他解决方案有点过于复杂......
document.addEventListener('click', e => {
if (e.target.closest('.element')) {
// .element has been clicked
}
}
如果您需要支持 Internet Explorer 或旧浏览器,可以使用polyfill。
将事件动态绑定到特定元素的替代方法可能是全局事件侦听器。因此,每次使用该元素上的另一个新元素事件更新 DOM 时,也会“捕获”。一个例子:
var mybuttonlist = document.getElementById('mybuttonlist');
mybuttonlist.addEventListener('click', e=>{
if(e.target.nodeName == 'BUTTON'){
switch(e.target.name){
case 'createnewbutton':
mybuttonlist.innerHTML += '<li><button name="createnewbutton">Create new button</button></li>';
break;
}
}
}, false);
ul {
list-style: none;
padding: 0;
margin: 0;
}
<ul id="mybuttonlist">
<li><button name="createnewbutton">Create new button</button></li>
</ul>
在这个例子中,我有一个<ul>
关于点击事件的事件监听器。因此,所有子元素都会发生一个事件。从我创建的简单事件处理程序中,您可以看到添加更多逻辑、更多按钮(具有不同或重复名称)、锚点等很容易。
总而言之,您可以将事件侦听器添加到文档而不是列表元素,捕获页面上的所有点击事件,然后在事件处理程序中处理点击事件。