javascript - 如何捕获自定义事件?
问题描述
我正在尝试创建一个自定义事件并捕获该事件。这是我简化的 HTML 和 JavaScript
let parent = document.getElementById('parent');
let child = document.getElementById('child');
parent.addEventListener('custom-event', () => alert("parent"), true);
child.addEventListener('custom-event', () => alert("child"));
let event = new Event('custom-event');
parent.dispatchEvent(event);
<div id="parent">
<p id="child">
Hello World
</p>
</div>
在这种情况下,我收到警报“父母”,但我没有收到子弹出窗口。
但是,如果我尝试使用已经存在的事件,如“点击”,它会起作用。
let parent = document.getElementById('parent');
let child = document.getElementById('child');
parent.addEventListener('click', () => alert("parent"), true);
child.addEventListener('click', () => alert("child"));
<div id="parent">
<p id="child">
Hello World
</p>
</div>
有什么方法/解决方法可以用来捕获自定义事件吗?
解决方案
正如莫里茨所说,您需要在孩子身上触发事件,因为它是最内部的元素。这样,事件就会冒泡到每个父母。事件的target
将始终是子元素,但currentTarget
事件的将是当前元素,因为它沿链向上。
您必须确保,useCapture
对于true
您希望为其选取事件的祖先元素。见:EventTarget.addEventListener
。
useCapture
A
Boolean
表示这种类型的事件将在被分派到DOM 树中它下面的listener
任何事件之前被分派给已注册的。EventTarget
通过树向上冒泡的事件不会触发指定使用捕获的侦听器。事件冒泡和捕获是传播嵌套在另一个元素中的元素中发生的事件的两种方式,当两个元素都注册了该事件的句柄时。事件传播模式确定元素接收事件的顺序。有关详细说明,请参阅 DOM Level 3 事件和 JavaScript 事件顺序。如果未指定,则
useCapture
默认为false
.
如果您从 中删除useCapture
参数(第二个参数)parent.addEventListener
,则只有祖父母会被接走,跟随孩子。它不会破坏链条,除非您取消孩子中的事件。
注意:如果要触发非本地事件,最好使用CustomEvent
构造函数。同样,如果需要,您可以直接调用构造函数。这只是一个浏览器安全的包装器。
let grandParent = document.getElementById('x-grand-parent');
let parent = document.getElementById('x-parent');
let child = document.getElementById('x-child');
grandParent.addEventListener('custom-event', (e) => console.log(e.currentTarget.id), true);
parent.addEventListener('custom-event', (e) => console.log(e.currentTarget.id), true);
child.addEventListener('custom-event', (e) => console.log(e.currentTarget.id));
triggerCustomEvent(child, 'custom-event');
function triggerCustomEvent(el, eventName, options) {
let opts = Object.assign({
canBubble: true,
cancelable: true,
detail: {}
}, options);
let event = null;
if (window.CustomEvent && typeof window.CustomEvent === 'function') {
event = new CustomEvent(eventName, {
detail: opts.detail
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, opts.canBubble, opts.cancelable, opts.detail);
}
el.dispatchEvent(event);
}
<div id="x-grand-parent">
<div id="x-parent">
<p id="x-child">
Hello World
</p>
</div>
</div>
推荐阅读
- asp.net-mvc - 没有 MediaTypeFormatter 可用于从媒体类型为“text/html”的内容中读取类型为“IEnumerable`1”的对象。错误
- pandas - 对多索引数据透视表 pandas 进行排序
- python - pip 在 Library/Python/2.7/bin 中安装包
- wordpress - 如何在谷歌云平台上安装 Wordpress 4.9
- regex - 我的 lambda 函数如何将匹配项作为 re.subn() 表达式中的参数?
- node.js - 退出代码 127 - 未知浏览器查询 `basedir=$(dirname "$(echo "$0" | sed -e 's`
- sql - 汇总分组中子查询的结果
- r - 删除列表中矩阵的 NA 行
- c - 使用 gcc target_clones 函数多版本控制静态链接存档时如何修复未定义的引用链接器错误
- angular - Angular 属性指令获取对其他同级属性引用的引用