Как отвязать слушателя, вызывающего 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; }

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

foxybagga
источник
Это решение не работает после $ ('# 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>

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

Val
источник
Я почти уверен, что это так - я недавно сделал это с дизайном. Сначала одним нажатием кнопки я предотвратил прокрутку на 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');
}) 
adardesign
источник
9

Вы можете восстановить действие по умолчанию (если это HREF), выполнив следующие действия:

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

crmpicco
источник
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();

Ссылка

Алиреза MH
источник
вы должны 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

Отключить:

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

Включить:

document.ontouchstart = function(e){ return true; }
Бриннер Феррейра
источник
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(); 
}

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

TennisVisuals
источник
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');
});
T.Todua
источник
-10

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

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

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

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

elb98rm
источник