在 vanilla js 中进行事件委托的最佳方式(最快/正确)是什么?例如,如果我在 jQuery 中有这个:$('#main').on('click', '.focused', function(){ settingsPanel();})...
在 vanilla js 中进行事件委托的最佳方式(最快/最合适)是什么?
例如如果我在 jQuery 中有这个:
$('#main').on('click', '.focused', function(){
settingsPanel();
});
我该如何将其转换为原生 js?或许可以用 .addEventListener()
我能想到的方法是:
document.getElementById('main').addEventListener('click', dothis);
function dothis(){
// now in jQuery
$(this).children().each(function(){
if($(this).is('.focused') settingsPanel();
});
}
但这似乎效率低下,特别是在 #main
有很多孩子的情况下。
那么这是正确的做法吗?
document.getElementById('main').addEventListener('click', doThis);
function doThis(event){
if($(event.target).is('.focused') || $(event.target).parents().is('.focused') settingsPanel();
}
无需改变内置原型(这会导致代码脆弱,并且经常会破坏某些功能),只需检查所点击的元素是否有与 .closest
所需选择器匹配的元素即可。如果有,则调用要调用的函数。例如,要翻译
$('#main').on('click', '.focused', function(){
settingsPanel();
});
在 jQuery 中,使用:
document.querySelector('#main').addEventListener('click', (e) => {
if (e.target.closest('#main .focused')) {
settingsPanel();
}
});
除非内部选择器也可能作为父元素存在(这可能非常不常见),否则将内部选择器单独传递给 .closest
(例如 .closest('.focused')
)就足够了。
当使用这种模式时,为了保持紧凑,我经常将代码的主要部分放在早期返回的下面,例如:
document.querySelector('#main').addEventListener('click', (e) => {
if (!e.target.closest('.focused')) {
return;
}
// code of settingsPanel here, if it isn't too long
});
现场演示:
document.querySelector('#outer').addEventListener('click', (e) => {
if (!e.target.closest('#inner')) {
return;
}
console.log('vanilla');
});
$('#outer').on('click', '#inner', () => {
console.log('jQuery');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="outer">
<div id="inner">
inner
<div id="nested">
nested
</div>
</div>
</div>