检测默认事件处理 [英] Detect default event handling

查看:29
本文介绍了检测默认事件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以检测到特定DOM事件是否绑定了任何事件处理程序(包括浏览器默认事件处理)-在Firefox的Gresemonkey代码中(EcmaScript 5.1 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);
备注:
-我不想用我的脚本停止传播,如果事件将传播到其他处理程序,我想停止我的脚本。
-如果JQuery-event-handlers-only解决方案不捕获默认浏览器事件处理程序,我对它们不感兴趣。
-如果这个功能确实不存在,请引用一些文章或博客,而不仅仅是您自己的观点。
-欢迎提出特殊建议,但我主要感兴趣的是是否存在一般解决方案。

更新:可接受的解决方案包括:

  • 我需要检查的if条件的详尽列表
  • 可从Firefox插件访问的非Java脚本方式
  • 解释Firefox如何知道单击有效的<a>元素应触发重新加载新URL+如何无法从Java脚本/插件访问此逻辑

推荐答案

此问题几乎与"How to do an action only when there is no default in Javascript / jQuery?"重复,只是作为Gresemonkey脚本编写者,您可以使用另一个(复杂)选项。

从您的问题看,您似乎想要为没有default action的节点设置default action,然后如果为给定事件触发任何其他事件处理程序,则中止该默认操作。对于这一点,没有"包罗万象的机制",而且几乎任何你尝试的技术都有可能在那里引起轰动。原因如下:

  1. Java脚本和Gresemonkey API都没有提供为给定节点列出事件的任何机制。有an old proposal,但从未实施过。

    然而,Firefox外接程序可以通过nsIEventListenerService列出事件,因此有可能您可以为该部分编写一个与Gresemonkey接口的帮助器外接程序。详细信息超出了此问题的范围。

  2. 同样,除非设置了event.defaultPrevented,否则不存在从Event object检测事件链中先前事件的机制。(通常不会。)

  3. 即使您可以列出节点X的事件侦听器,这对父节点上的回退侦听器也没有帮助。现代JS库可以,有时确实可以使任何旧节点都可以点击。和/或他们可以设置监听程序,例如,获取所有点击事件,但实际上不执行任何操作,除非原始目标是某个特定节点。

    /li>

一个好的折衷策略是跟随另一个问题的线索,并且不对具有默认操作的节点执行任何操作。
要处理右击或居中单击,请选中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; 
    }
    ...

其中:

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);
}

这篇关于检测默认事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆