如何取消绑定调用event.preventDefault()的侦听器(使用jQuery)?


128

jQuery切换默认情况下会调用preventDefault(),因此默认设置无效。您不能单击复选框,您不能单击链接等

是否可以恢复默认处理程序?


你能举一些例子代码吗?
乔乔(Jojo)

4
标题中的问题是一个了不起的问题!太糟糕了,实际的问题不是……我希望在这里找到答案(在可能的情况下),如何才能(在可能的情况下)“取消” preventDefault调用它的效果。当前,这个问题实际上是“如何将事件侦听器与jQuery绑定?”。
Stijn de Witt

Answers:


80

就我而言:

$('#some_link').click(function(event){
    event.preventDefault();
});

$('#some_link').unbind('click'); 是还原默认操作的唯一方法。

如在这里看到的那样:https : //stackoverflow.com/a/1673570/211514


2
如果此元素具有另一个单击处理程序,则您将解除绑定的所有事件的绑定,不仅阻止了处理程序...
Aure77 '16

56

它相当简单

让我们假设你做类似的事情

document.ontouchmove = function(e){ e.preventDefault(); }

现在将其恢复为原始状态,请执行以下操作...

document.ontouchmove = function(e){ return true; }

从这个网站


$('#a_link')。click(function(e){e.preventDefault();});之后,此解决方案不起作用 使用取消绑定功能。
Denis Makarskiy 2015年

2
您提供的链接已损坏。
堆叠

16

无法还原,preventDefault()但是您可以欺骗它:)

<div id="t1">Toggle</div>
<script type="javascript">
$('#t1').click(function (e){
   if($(this).hasClass('prevented')){
       e.preventDefault();
       $(this).removeClass('prevented');
   }else{
       $(this).addClass('prevented');
   }
});
</script>

如果您想更进一步,甚至可以使用触发按钮来触发事件。


我很确定是这样-我最近在设计上做了这个。首先,单击按钮时,我通过在touchmove事件中将e.preventDefault添加到iphone中来防止在iphone中滚动,然后在完成动画之后,我返回true,并且它像一种魅力一样工作。
foxybagga 2012年

11
function DoPrevent(e) {
  e.preventDefault();
  e.stopPropagation();
}

// Bind:
$(element).on('click', DoPrevent);

// UnBind:
$(element).off('click', DoPrevent);

它为我工作的方式是:$(document).off('touchmove'); $(document).on('touchmove',function(){return true;});
rogervila

9

在某些情况下*,最初可以return false代替e.preventDefault(),然后在要将默认值恢复为时使用return true

*表示当您不介意事件冒泡并且不e.stopPropagation()e.preventDefault()

另请参见类似的问题(也在堆栈溢出中)

或使用复选框,您可以输入以下内容:

$(element).toggle(function(){
  $(":checkbox").attr('disabled', true);
  },
function(){
   $(":checkbox").removeAttr('disabled');
}) 

9

您可以通过执行以下操作恢复默认操作(如果遵循HREF):

window.location = $(this).attr('href');


2
想法是正确的,但是开箱即用的代码对我不起作用(除非这只是jquery中的语法更改),我使用过:window.location = $(this).attr('href');
Modika 2015年

3

如果它是一个链接,$(this).unbind("click");则将重新启用该链接单击,并且将恢复默认行为。

我创建了一个演示JS小提琴来演示其工作原理:

这是JS小提琴的代码:

HTML:

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<a href="http://jquery.com">Default click action is prevented, only on the third click it would be enabled</a>
<div id="log"></div>

Javascript:

<script>
var counter = 1;
$(document).ready(function(){
$( "a" ).click(function( event ) {
  event.preventDefault();

  $( "<div>" )
    .append( "default " + event.type + " prevented "+counter )
    .appendTo( "#log" );

    if(counter == 2)
    {
        $( "<div>" )
    .append( "now enable click" )
    .appendTo( "#log" );

    $(this).unbind("click");//-----this code unbinds the e.preventDefault() and restores the link clicking behavior
    }
    else
    {
        $( "<div>" )
    .append( "still disabled" )
    .appendTo( "#log" );
    }
    counter++;
});
});
</script>

2

测试这段代码,我想解决您的问题:

event.stopPropagation();

参考


您必须在防止默认值的处理程序之前对处理程序进行stopPropagation。如果您的其他处理程序已在冒泡阶段注册,则可以在capturePhase上执行此操作。
Vitim.us

2

最好的方法是使用名称空间。这是一种安全的方法。.rb是命名空间,可确保取消绑定功能在特定的keydown上起作用,而不在其他keydown上起作用。

$(document).bind('keydown.rb','Ctrl+r',function(e){
            e.stopImmediatePropagation();
            return false;
        });

$(document).unbind('keydown.rb');

ref1:http//idodev.co.uk/2014/01/safely-binding-to-events-using-namespaces-in-jquery/

ref2:http//jqfundamentals.com/chapter/events



1

事件接口的preventDefault()方法告诉用户代理,如果未明确处理事件,则不应像通常那样采取其默认操作。该事件将继续照常传播,除非事件监听器之一调用stopPropagation()或stopImmediatePropagation(),它们中的任何一个都会立即终止传播。

在事件流的任何阶段调用preventDefault()都会取消事件,这意味着实现通常不会由于事件而执行任何默认操作。

您可以使用Event.cancelable检查事件是否可取消。为不可取消的事件调用preventDefault()无效。

window.onKeydown = event => {
    /*
        if the control button is pressed, the event.ctrKey 
        will be the value  [true]
    */

    if (event.ctrKey && event.keyCode == 83) {
        event.preventDefault();
        // you function in here.
    }
}

0

我有一个问题,只有在完成一些自定义操作(在表单上启用否则被禁用的输入字段)后,才需要默认操作。我将默认操作(submit())包装到了自己的递归函数(dosubmit())中。

var prevdef=true;
var dosubmit=function(){
    if(prevdef==true){
        //here we can do something else first//
        prevdef=false;
        dosubmit();
    }
    else{
        $(this).submit();//which was the default action
    }
};

$('input#somebutton').click(function(){dosubmit()});

1
一般注意事项:尽管有些编码人员觉得if (predef == true)更加明确,但是您无缘无故地在JS代码中添加了7个字符。if (prevdef)可读性强。另外,您在.click(dosubmit)执行与.click(function(){dosubmit()})未传递任何参数相同的操作时添加了一个冗余的匿名事件处理程序。
Gone Coding,

0

使用布尔值:

let prevent_touch = true;
document.documentElement.addEventListener('touchmove', touchMove, false);
function touchMove(event) { 
    if (prevent_touch) event.preventDefault(); 
}

我在渐进式Web应用程序中使用它来防止在某些“页面”上滚动/缩放而在其他页面上允许滚动/缩放。


0

您可以设置为2个班级。将JS脚本设置为其中之一后,当您想要禁用脚本时,只需从此表单中删除具有绑定脚本的类。

HTML:

<form class="form-create-container form-create"> </form>   

JS

$(document).on('submit', '.form-create', function(){ 
..... ..... ..... 
$('.form-create-container').removeClass('form-create').submit();

});

-3
$('#my_elementtt').click(function(event){
    trigger('click');
});

-10

我不确定您的意思是什么:但这是解决类似(可能相同)问题的解决方案...

我经常使用preventDefault()来拦截项目。但是:这不是唯一的拦截方法...通常,您可能只需要一个“问题”,其后行为将像以前一样继续或停止。在最近的情况下,我使用以下解决方案:

$("#content").on('click', '#replace', (function(event){ return confirm('Are you sure you want to do that?') }));

基本上,“防止默认设置”是指拦截并执行其他操作:“确认”旨在用于...很好-确认!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.