我试图弄清楚如何将事件绑定到动态创建的元素。我需要事件在元素上持续存在,即使它被破坏和再生。显然,使用jQuery的live函数很容易,但是用原生JavaScript实现它们会是什么样子呢?
carvr3hs1#
下面是一个简单的例子:
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)。
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); } }); }
型
hts6caw32#
除了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'); });
字符串
wfsdck303#
其他的解决方案有点过于复杂了。。
document.addEventListener('click', e => { if (e.target.closest('.element')) { // .element has been clicked } }
字符串有一个polyfill,以防您需要支持Internet Explorer或旧浏览器。
wvt8vs2t4#
将事件动态绑定到特定元素的替代方法可以是全局事件侦听器。因此,每次您使用该元素上的另一个新元素事件更新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>上有一个事件侦听器,用于单击事件。因此,所有子元素都会发生事件。从我创建的简单事件处理程序中,您可以看到添加更多逻辑、更多按钮(具有不同或重复的名称)、锚点等非常容易。如果全面考虑,您可以将eventlistener添加到document而不是list元素,捕获页面上的所有单击事件,然后在事件处理程序中处理单击事件。
<ul>
64jmpszr5#
使用.matches()元素API,这变得更简单。
.matches()
const selector = '.item' document.addEventListener('click', (e) => { if ( ! e.target.matches(selector) ) { return } // do stuff here })
字符串jQuery等价物:
$('.item').live( 'click', (e) => { // do stuff here })
5条答案
按热度按时间carvr3hs1#
下面是一个简单的例子:
字符串
基本思想是,您希望将事件处理程序附加到文档,并让事件在DOM中冒泡。然后,检查
event.target
属性,看看它是否与所需的条件匹配(在本例中,只需要元素的id
)。编辑:
@shabunc发现我的解决方案有一个相当大的问题--子元素上的事件不会被正确检测到。解决这个问题的一种方法是查看祖先元素,看看是否有指定的
id
:型
hts6caw32#
除了Andrew的帖子和Binyamin的评论,也许这是一个选择:
这样你就可以使用'nav .item a'作为选择器。基于安德鲁的代码。
字符串
wfsdck303#
其他的解决方案有点过于复杂了。。
字符串
有一个polyfill,以防您需要支持Internet Explorer或旧浏览器。
wvt8vs2t4#
将事件动态绑定到特定元素的替代方法可以是全局事件侦听器。因此,每次您使用该元素上的另一个新元素事件更新DOM时,也将“捕获”。举个例子:
在这个例子中,我在
<ul>
上有一个事件侦听器,用于单击事件。因此,所有子元素都会发生事件。从我创建的简单事件处理程序中,您可以看到添加更多逻辑、更多按钮(具有不同或重复的名称)、锚点等非常容易。如果全面考虑,您可以将eventlistener添加到document而不是list元素,捕获页面上的所有单击事件,然后在事件处理程序中处理单击事件。
64jmpszr5#
使用
.matches()
元素API,这变得更简单。字符串
jQuery等价物:
型