jQuery: 如何在输入和点击事件中使用preventDefault()方法阻止默认行为?

9

我希望能够在用户右键单击输入字段时禁用默认的上下文菜单,以便我可以显示自定义的上下文菜单。一般来说,通过以下方式禁用右键菜单相当简单:

$([whatever]).bind("click", function(e) { e.preventDefault(); });

事实上,我可以在几乎所有元素上执行此操作,但是在FF中无法在输入字段上执行此操作——有人知道原因或可以向我指出一些文档吗?

这是我正在使用的相关代码,谢谢大家。

HTML:

<script type="text/javascript">
 var r = new RightClickTool();
</script>

<div id="main">
  <input type="text" class="listen rightClick" value="0" />  
</div>

JS:

function RightClickTool(){

var _this = this;
var _items = ".rightClick";

$(document).ready(function() { _this.init(); });

this.init = function() {
 _this.setListeners(); 
}

this.setListeners = function() {
 $(_items).click(function(e) {
  var webKit = !$.browser.msie && e.button == 0;
  var ie = $.browser.msie && e.button == 1;

  if(webKit||ie)
  { 

   // Left mouse...do something()

  } else if(e.button == 2) {
   e.preventDefault(); 

   // Right mouse...do something else();
  }

 });
}

} // Ends Class

编辑:

抱歉,经过阅读评论后我意识到需要澄清一些事情。

1)上面的代码确实可以工作……在某种程度上。 该代码能够排序出哪个按钮被点击了,但它并不关心我是否使用了e.preventDefault(),右键菜单仍然弹出。换句话说,如果您在e.button上放置一个警报,您将得到左键和右键的1或0...但它仍会展示该默认菜单!

2)如果我将jQuery选择器放在任何其他元素(而不是输入框)上,那么所有内容都将正常工作,Firefox将尊重preventDefault()调用,并且默认的右键菜单将不会显示。


仅使用 return false 怎么样? - David Murdoch
另外,尝试使用 e.which 而不是 e.button - karim79
可能与此相关:https://dev59.com/FEnSa4cB1Zd3GeqPO47I - scott
3个回答

12

一个跨浏览器的解决方案,用于禁用默认的上下文菜单:

window.oncontextmenu = function() { return false };

要仅在给定元素内捕获contextmenu事件,请使用:

document.getElementById('myElement').oncontextmenu=function(){

    // Code to handle event
    return false;
}

如果您尝试使用除oncontextmenu以外的方法中断右键单击事件,则会根据确切的事件场景和浏览器而产生不同的结果。

在jQuery中:

$('myElement').bind('contextmenu', function(){

    // Handle right-click event.
    return false;
});

您还可以使用jQuery的event.which来确定按下了哪个按钮,但仍需要取消默认的contextmenu事件:

   // Cancel default oncontextmenu event.
    $(element).bind('contextmenu', function(){ return false });

    $(element).mousedown(function(event){

        switch (event.which)

            case 1:
            // Left mouse
            break;

            case 2:
            // Middle mouse
            break;

            case 3:
            // Right mouse.
            break;

    });

我已经在IE6(在Wine下)、Chrome 11、Firefox 3.6、Opera 11和Safari中进行了测试。


为什么 if (event.which==3) { //something } 会取消上下文菜单禁用? - Andreas

4

对不起,各位,我知道这是一个回避的“答案”,因为我从未能够弄清楚为什么 Webkit 浏览器不喜欢你干扰输入字段事件,但无论如何,这个方法有效。所以解决方案是将监听器应用于整个窗口,然后只需询问目标是否具有你想要应用效果的类...然后从那里开始。说实话,这可能是更好的解决方案,因为对于我的特定应用程序,这允许我将此功能应用于任何我想要的元素。

var _class = "input.hideRightClick";

this.setListeners = function() {
    $(window).click(function(e) {
        if($(e.target).is(_class))
        {
            e.preventDefault(); 
            alert("hide!");
        }
    });
}

0

我刚在Firefox 3.6中进行了测试,它正在进入第一个if语句,因此e.preventDefault()从未被调用。

  var webKit = !$.browser.msie && e.button == 0; // TRUE IN FIREFOX 3.6

  var ie = $.browser.msie && e.button == 1;

  if(webKit||ie)
  { 

   // Left mouse...do something()

  } else if(e.button == 2) {
   e.preventDefault(); 

   // Right mouse...do something else();
  }

等等,右键点击时它会返回 true 吗? A)不应该。 B)在我的机器上(FF 3.5.7)没有这种情况。 - Jason
此外,即使我在if/else-if之前/之外放置e.preventDefault()(这意味着它应该无论如何都会触发),ff似乎也不在意。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接