事件监听器三级(从父级到孙级)
Event listener three levels (from parent to grandchild)
我在将事件侦听器附加到孙子时遇到了一些问题。
父点击和子点击都按预期工作,只有孙点击不会触发。
这是我当前的代码:
/* Parent */
$('body').on('click', 'div.left-menu-item', function (e) {
e.preventDefault();
console.log('parent'); // <-- this works
});
/* Child */
$('body').on('click', 'div.left-menu-item div.dropdown', function(e){
e.stopPropagation();
e.stopImmediatePropagation();
console.log('child'); // <-- this works
});
/* Grandchild */
$('body').on('click', 'div.left-menu-item div.dropdown-menu.show a.edit', function(e){
e.stopPropagation();
e.stopImmediatePropagation();
console.log('grandchild'); // <-- this does NOT work
});
问题的按钮标记是:
<a class="btn edit" data-unsp-sanitized="clean">
<i class="fas fa-fw fa-pen"></i> <span>Edit</span>
</a>
我也试过将孙事件监听器设置为:
$('body').on('click', 'a.edit', function(e){
console.log('grandchild'); <-- this doesnt work either
});
新更新。
我添加了一个带通配符的点击监听器,这样我就可以监听所有的点击:
$('body').on('click', '*', function(e){
console.log('clicked');
});
总共触发了 20 次点击,但是当我点击 .edit 时,仍然没有检测到点击。
如果我手动触发点击 $('.edit').trigger('click');
它有效..
您还可以通过仅将侦听器附加到父级并检查谁发出了事件(通过 类 或节点 name/type)来说明事件冒泡的优势。
$('div.left-menu-item').on('click', function(e){
if( $(e.target).hasClass('dropdown') ) {
// child logic
} else if ( $(e.target).hasClass('edit') ) {
// grandchild logic
}
});
问题已解决。
在 $(document).ready
中,我创建了一个名为 document 的实际对象(愚蠢,对吧?),这让一切变得疯狂。
所以我刚刚将 var document = ....;
重命名为 var documentObj = ....;
,一切都按预期进行。
我仍然对某些事件侦听器为何起作用感到困惑。我知道重写文档是不应该发生的事情,并且可能重写文档导致 $('body').on('...', '...
无法按预期工作,因为 body 是文档的子项?但这并不能解释为什么那么多事件监听器起作用而只有一个没有触发点击事件。
我在将事件侦听器附加到孙子时遇到了一些问题。
父点击和子点击都按预期工作,只有孙点击不会触发。
这是我当前的代码:
/* Parent */
$('body').on('click', 'div.left-menu-item', function (e) {
e.preventDefault();
console.log('parent'); // <-- this works
});
/* Child */
$('body').on('click', 'div.left-menu-item div.dropdown', function(e){
e.stopPropagation();
e.stopImmediatePropagation();
console.log('child'); // <-- this works
});
/* Grandchild */
$('body').on('click', 'div.left-menu-item div.dropdown-menu.show a.edit', function(e){
e.stopPropagation();
e.stopImmediatePropagation();
console.log('grandchild'); // <-- this does NOT work
});
问题的按钮标记是:
<a class="btn edit" data-unsp-sanitized="clean">
<i class="fas fa-fw fa-pen"></i> <span>Edit</span>
</a>
我也试过将孙事件监听器设置为:
$('body').on('click', 'a.edit', function(e){
console.log('grandchild'); <-- this doesnt work either
});
新更新。
我添加了一个带通配符的点击监听器,这样我就可以监听所有的点击:
$('body').on('click', '*', function(e){
console.log('clicked');
});
总共触发了 20 次点击,但是当我点击 .edit 时,仍然没有检测到点击。
如果我手动触发点击 $('.edit').trigger('click');
它有效..
您还可以通过仅将侦听器附加到父级并检查谁发出了事件(通过 类 或节点 name/type)来说明事件冒泡的优势。
$('div.left-menu-item').on('click', function(e){
if( $(e.target).hasClass('dropdown') ) {
// child logic
} else if ( $(e.target).hasClass('edit') ) {
// grandchild logic
}
});
问题已解决。
在 $(document).ready
中,我创建了一个名为 document 的实际对象(愚蠢,对吧?),这让一切变得疯狂。
所以我刚刚将 var document = ....;
重命名为 var documentObj = ....;
,一切都按预期进行。
我仍然对某些事件侦听器为何起作用感到困惑。我知道重写文档是不应该发生的事情,并且可能重写文档导致 $('body').on('...', '...
无法按预期工作,因为 body 是文档的子项?但这并不能解释为什么那么多事件监听器起作用而只有一个没有触发点击事件。