【问题标题】:javascript: can't set oncontextmenu property to pre-defined functionjavascript:无法将 oncontextmenu 属性设置为预定义函数
【发布时间】:2010-01-03 10:19:02
【问题描述】:

我正在尝试编写一个函数来读取 div 项的 oncontextmenu 事件。 (我需要它来确定是否按下了 ctrl 键,例如使用 e.ctrlKey。)

这行得通:

<div id="item_2" class="lineitem" align=center oncontextmenu="alert('foo');">test</div>

但这不是:

<script language="JavaScript">
function asdf(e){
    alert('foo');
}
</script>
<div id="item_2" class="lineitem" align=center oncontextmenu=asdf>test</div>

我需要做什么来修复第二个?

谢谢。

【问题讨论】:

    标签: javascript right-click


    【解决方案1】:
    <div oncontextmenu="asdf(event)">
    
    <script type="text/javascript">
        function asdf(event){
            if (event.ctrlKey)
                alert('foo');
        }
    </script>
    

    为什么会这样:在由事件处理程序属性字符串创建的匿名函数内部,有一个局部变量 event 初始化为指向事件实例。 IE 有一个损坏的事件模型,但这段代码仍然有效,因为event 现在不是指局部变量,而是window.event 全局变量。

    但是,现在您通常希望避免使用事件处理程序属性。最好从脚本本身分配​​事件处理程序,例如:

    <div id="thing">
    
    <script type="text/javascript">
        document.getElementById('thing').oncontextmenu= function(event) {
            if (event===undefined) event= window.event; // fix for IE
            if (event.ctrlKey)
                alert('foo');
        };
    </script>
    

    将它放在脚本中也意味着您的 HTML 保持可验证性。 (oncontextmenu 是一个 IE 扩展,直到 HTML5 才会标准化。)

    您也可以将相同的功能迁移到addEventListener,但请注意,IE 不支持它,因此您需要嗅探addEventListener 的存在,如果缺少,请改用IE 特定的attachEvent。如果您不需要多个处理程序来处理同一对象上的同一事件,则只需使用老式的onevent 样式处理程序会更容易(并且与古老的浏览器更兼容)。

    请注意,contextmenu 是一个不可靠的事件。并非所有浏览器都支持它,它可能被禁用或仍然会显示浏览器的真实上下文菜单,在 Mac 上,获取它的常用方法是按住 Control 键单击,这可能会混淆您对 ctrlKey 的检查。另外,当然还有可访问性问题。将 Web 应用程序中的上下文菜单仅用作快捷功能,而不是必不可少的访问方法。

    【讨论】:

    • 你想在属性一中使用window.event||(arguments&amp;&amp;arguments[0])而不是event
    • 是否有需要的浏览器?我记得,第一个参数被命名为event 是在 Netscape 4.0 中引入事件对象时由 JavaScript 1.2 指定的,此后每个浏览器都复制了它(当然除了 IE,它的 window.event 出现混乱源于对 onclick="f(event)" 应该起作用的误解)。
    【解决方案2】:
    oncontextmenu="asdf()"
    

    您不能直接使用属性值分配预定义函数。只有匿名函数(其中function () {} 被替换为attribute=""。这使得捕获事件对象相当困难(也许是不可能的,这不是我曾经觉得需要调查)。

    如果您想直接分配函数,请使用 JavaScript 和 attachEvent/addEventListener。

    【讨论】:

    • 哇哦! addEventListener 工作;谢谢。为了将来参考,这里是允许我捕获事件的解决方案: function load() { var el = document.getElementById("item_2"); el.addEventListener("contextmenu", asdf, false); }
    • arguments[0] 在事件监听器属性中是事件对象。
    【解决方案3】:
    oncontextmenu="asdf()"
    

    应该有效,不是吗?

    【讨论】:

    • 是的,但我需要 asdf() 将事件作为输入(以便我可以检查是否按住 ctrl)。
    猜你喜欢
    • 2011-11-20
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多