在 JavaScript 中,手动控制事件监听器的顺序
假设 FORM 包含 INPUT,则具有以下侦听器:
JavaScript
function formFirst(e) { ... }
function formLast(e) { ... }
function inputFirst(e) { ... }
function inputLast(e) { ... }
function middle(e) { ... }
document.getElementById('form').addEventListener('change',formFirst,true);
document.getElementById('form').addEventListener('change',formLast,false);
document.getElementById('input').addEventListener('change',inputFirst,true);
document.getElementById('input').addEventListener('change',inputLast,false);
所需的触发顺序
formFirst() // normal - outer element, useCapture = true
inputFirst() // normal - triggering element, declared first
middle() // -- how to do this?
inputLast() // normal - triggering element, declared second
formLast() // normal - outer element, useCapture = false
问题的性质和尝试的解决方案
FORM 级别的自己的代码,formFirst
、formLast
和 middle
,但无法访问 INPUT 代码、inputFirst
和 inputLast
- 尽管可以在 INPUT 上添加自己的侦听器。
尝试 1 修改 formFirst()
以创建并分派新的 change Event
(将在 formFirst
中被忽略)会调用 inputFirst()
,但无法停止传播以防止随后调用 inputLast()
。
尝试2添加middle
作为侦听器添加到INPUT,但不能保证相同类型和相同useCapture的两个侦听器的触发顺序。
尝试 2 的前提不正确 - 触发顺序由目标元素内的声明顺序决定。
规则
- 以下是
使用
useCapture=false
触发非目标元素的 ,从最外层元素开始并向目标元素努力a) 如果同一元素有多个
useCapture=true
触发,则声明顺序。 在目标元素处,声明顺序,无论
useCapture
使用
useCapture=false
触发非目标元素,从最里面的元素开始并远离目标元素a) 如果同一元素有多个
useCapture=false
触发,则声明顺序。
Assuming that FORM contains INPUT, have the following listeners:
JavaScript
function formFirst(e) { ... }
function formLast(e) { ... }
function inputFirst(e) { ... }
function inputLast(e) { ... }
function middle(e) { ... }
document.getElementById('form').addEventListener('change',formFirst,true);
document.getElementById('form').addEventListener('change',formLast,false);
document.getElementById('input').addEventListener('change',inputFirst,true);
document.getElementById('input').addEventListener('change',inputLast,false);
Desired order of firing
formFirst() // normal - outer element, useCapture = true
inputFirst() // normal - triggering element, declared first
middle() // -- how to do this?
inputLast() // normal - triggering element, declared second
formLast() // normal - outer element, useCapture = false
Nature of problem and attempted solutions
Own code at FORM level, formFirst
, formLast
and middle
, but have no access to INPUT code, inputFirst
and inputLast
- although could add own listeners on the INPUT.
Attempt 1 modify formFirst()
to create and dispatch a new change Event
(would be ignored within formFirst
) that would call inputFirst()
, but have no way of stopping propagation to prevent inputLast()
being called subsequently.
Attempt 2 add middle
added as listener to INPUT, but cannot guarantee firing order of two listeners of same type and same useCapture.
Premise of Attempt 2 is incorrect - firing order is determined by declaration order within the target Element.
Here are the rules
non-target Element triggers with
useCapture=false
, starting at the outermost Element and working toward the target Elementa) if more than one
useCapture=true
triggers for same element, then order of declaration.at target Element, order of declaration, regardless of
useCapture
non-target Element triggers with
useCapture=false
, starting at the innermost Element and working away from the target Elementa) if more than one
useCapture=false
triggers for same Element, then order of declaration.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这正好回答了您的问题。请随时发表评论\联系我以获取更多信息。
----- 编辑 ------
好的,我只是按照承诺的那样玩了一下,我发现了一个非常简单的解决方案:
注意:
另一种方法是自己编写事件处理。这是一个例子。转发这篇文章。
I think that this answers just your question. feel free to comment\contact me for more info.
----- edit ------
OK, I just played with it a little as promised, and I found a very simple solution:
notice:
An alternative is writing the event handling on your own. here is an example for that. relaying on this article.