是否可以检测特定 DOM 事件是否绑定了任何事件处理程序(包括浏览器默认事件处理)- 在 Firefox 的 Greasemonkey 代码中(EcmaScript 5.1 严格模式 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode)?
到目前为止,我设法在选择文本时取消点击事件处理,但是我想在以下所有情况下取消我的事件处理其中点击事件触发默认操作:
- 选择页面上的文本
- 显示上下文菜单(即右键单击)
- 已跟踪链接(左键单击
<a>
)
- 表单元素被操纵(文本框获得焦点,光标开始闪烁,单选按钮被选中,...)
- 处理该事件的其他一些 JavaScript 代码(例如显示弹出帮助对话框)
有没有包罗万象的机制为此还是我需要明确地拼写代码中的所有情况?
以下代码是我检测发生选择的方式:
var toggleHighlight = function(){
var oldTargt;
return function(e){
targt = e.target;
sel = window.getSelection();
if (!sel.isCollapsed && sel.containsNode(targt, true)) {
return;
}
...
oldTargt = targt;
}()
document.addEventListener('click', toggleHighlight);
Notes:
- I don't want to STOP propagation with my script, I want to stop MY SCRIPT if the event will be propagated to other handler.
- I'm not interested in JQuery-event-handlers-only https://stackoverflow.com/questions/1236067/test-if-event-handler-is-bound-to-an-element-in-jquery solutions if they don't catch default browser event handlers.
- If this feature does not indeed exist, please cite some articles or blogs, not just your own opinion.
- Particular suggestions are welcome, but I'm mainly interested in the existence of a general solution.
Update:可接受的解决方案包括:
- 详尽的清单
if
我需要检查的条件
- 可通过 Firefox 插件访问的非 JavaScript 方式
- 解释 Firefox 如何知道点击有效
<a>
元素应该触发新 URL 的重新加载+如何无法从 javascript/插件访问此逻辑
这个问题几乎是重复的“如何仅在 Javascript / jQuery 中没有默认值时执行操作?” https://stackoverflow.com/q/3152075/331508,除了作为一名 Greasemonkey 脚本编写者之外,还有一个(复杂的)选项可供您使用。
从你的问题来看,你似乎想设置一个默认动作 http://www.w3.org/TR/DOM-Level-3-Events/#glossary-default-action对于没有事件处理程序的节点,如果给定事件触发任何其他事件处理程序,则中止该默认操作。对此没有“包罗万象的机制”,几乎您尝试的任何技术都可能会破坏某些页面。原因如下:
-
javascript 和 Greasemonkey API 都没有提供任何列出给定节点事件的机制。有一个旧提案 https://stackoverflow.com/q/7810534/331508,但从未实施过。
However,Firefox 附加组件可以通过以下方式列出事件nsIEventListenerService 服务 https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIEventListenerService,所以有一个可能性您可以为该部分编写一个与 Greasemonkey 交互的辅助插件。细节(远远)超出了这个问题的范围。
同样,没有机制可以从事件链中检测先前事件事件对象 https://developer.mozilla.org/en-US/docs/DOM/event, 除非event.defaultPrevented
已设置。 (通常不会。)
即使您可以列出事件侦听器node X,这对父节点上的后备侦听器没有帮助。现代 JS 库可以(有时确实)使任何旧节点可点击。和/或他们可能会设置一个监听器,比如说,document
that gets所有点击事件,但实际上并非如此do除了原始目标是某个特定节点时之外的任何情况。
一个好的妥协策略是跟随另一个问题的引导,不对具有 a 的节点执行任何操作默认动作.
要处理右键单击或中心单击,请选中event.which
.
因此,您可以将以下片段添加到您的支票中:
return function(e){
targt = e.target;
sel = window.getSelection();
if (e.which != 1) {
return; //-- Abort on anything that is not a left-click.
}
if (e.defaultPrevented) {
return; //-- The one time we know that some other handler fired.
}
if (isInteractiveElement (targt) ) {
// Do nothing for elements that trigger browser actions
return;
}
...
where:
function isInteractiveElement (node) {
var intElems = [
//-- Must be uppercase
"A", "BUTTON", "INPUT", "TEXTAREA", "VIDEO", "MAP", "OBJECT"
];
if (intElems.indexOf (node.nodeName) >= 0) {
return true;
}
else if (node.nodeName === "BODY") {
return false;
}
return isInteractiveElement (node.parentNode);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)