Как отвязать слушателя, вызывающего event.preventDefault () (с помощью jQuery)?


128

jquery toggle по умолчанию вызывает preventDefault (), поэтому значения по умолчанию не работают. нельзя установить флажок, нельзя щелкнуть ссылку и т. д.

можно ли восстановить обработчик по умолчанию?


Вы можете привести пример кода?
Jojo

4
Вопрос в названии просто фантастический! Жаль, что на самом деле вопрос не в том ... Я надеялся найти здесь ответ на то, как (если это вообще возможно) мы можем "сбросить" эффект preventDefaultпосле того, как он был вызван. На данный момент это вопрос: «Как мне отвязать прослушиватель событий с jQuery?».
Stijn de Witt

Ответы:


80

В моем случае:

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

$('#some_link').unbind('click'); работал как единственный способ восстановить действие по умолчанию.

Как видно здесь: https://stackoverflow.com/a/1673570/211514


2
Если у этого элемента есть другой обработчик кликов, вы отключаете все присоединенные события, а не только предотвращенный обработчик ...
Aure77

56

Это довольно просто

Предположим, вы делаете что-то вроде

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

теперь, чтобы вернуть его к исходной ситуации, сделайте следующее ...

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

С этого сайта .


Это решение не работает после $ ('# a_link'). Click (function (e) {e.preventDefault ();}); использовать функцию отмены привязки.
Денис Макарский

2
Ссылка, которую вы предоставили, не работает.
сложено

16

Невозможно восстановить a, 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>

Если вы хотите пойти дальше, вы даже можете использовать кнопку запуска для запуска события.


Я почти уверен, что это так - я недавно сделал это с дизайном. Сначала одним нажатием кнопки я предотвратил прокрутку на iphone, добавив e.preventDefault к событию on touchmove, а затем, после того, как анимация была завершена, я вернул true, и это сработало как шарм.
foxybagga 05

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

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

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

Для меня это сработало: $ (document) .off ('touchmove'); $ (документ) .on ('touchmove', function () {return true;});
rogervila 03

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

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 для обработчика, который происходит перед обработчиком, предотвращающим default. Вы можете сделать это в capturePhase, если ваш другой обработчик зарегистрирован в пузырьковой фазе.
Vitim.us

2

Лучший способ сделать это - использовать пространство имен. Это безопасный и надежный способ. Здесь .rb - это пространство имен, которое гарантирует, что функция отмены привязки работает с этой конкретной клавишей, но не с другими.

$(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 () интерфейса Event сообщает пользовательскому агенту, что если событие не обрабатывается явным образом, его действие по умолчанию не должно выполняться, как обычно. Событие продолжает распространяться как обычно, если один из его прослушивателей событий не вызывает 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)это более явное, вы добавляете 7 символов в свой JS-код без всякой причины. 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(); 
}

Я использую это в прогрессивном веб-приложении, чтобы предотвратить прокрутку / масштабирование одних «страниц», но разрешить другие.


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

});


-10

Я не уверен, что вы имеете в виду: но вот решение аналогичной (и, возможно, той же) проблемы ...

Я часто использую preventDefault () для перехвата элементов. Однако: это не единственный метод перехвата ... часто вам может потребоваться просто «вопрос», после которого поведение будет продолжаться, как прежде, или прекратится. В недавнем случае я использовал следующее решение:

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

По сути, «предотвратить по умолчанию» предназначено для перехвата и выполнения чего-то еще: «подтверждение» предназначено для использования в ... ну - подтверждении!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.