Como desvincular um ouvinte que está chamando event.preventDefault () (usando jQuery)?

128

O jquery toggle chama preventDefault () por padrão, para que os padrões não funcionem. você não pode clicar em uma caixa de seleção, não pode clicar em um link etc. etc

é possível restaurar o manipulador padrão?

Stijn de Witt
fonte
Você pode dar um exemplo de código?
Jojo
4
A pergunta no título é fantástica! Pena que a pergunta real não é ... Eu esperava encontrar aqui a resposta de como (se possível) podemos "desabilitar" o efeito de preventDefaultdepois que ela foi chamada. Atualmente, esta pergunta é realmente 'como desassociar um ouvinte de evento com o jQuery?'.
Stijn de Witt

Respostas:

80

No meu caso:

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

$('#some_link').unbind('click'); funcionou como o único método para restaurar a ação padrão.

Como visto aqui: https://stackoverflow.com/a/1673570/211514

klaus
fonte
2
Se esse elemento tem um outro manipulador de clique, você desvincular todos os eventos ligados manipulador não só impediu ...
Aure77
56

É bastante simples

Vamos supor que você faça algo como

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

agora, para reverter para a situação original, faça o seguinte ...

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

A partir deste site .

foxybagga
fonte
Esta solução não funciona após $ ('# a_link'). Click (function (e) {e.preventDefault ();}); use a função unbind.
Denis Makarskiy
2
O link que você forneceu está quebrado.
Empilhado
16

Não é possível restaurar um, preventDefault()mas o que você pode fazer é enganá-lo :)

<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>

Se você quiser dar um passo adiante, pode usar o botão de acionamento para acionar um evento.

Val
fonte
Tenho certeza de que sim - fiz isso recentemente em um design. Inicialmente, com o clique de um botão, evitei a rolagem em um iphone adicionando e.preventDefault ao evento touchmove e, depois que a animação foi concluída, retornei true e funcionou como um encanto.
foxybagga
11
function DoPrevent(e) {
  e.preventDefault();
  e.stopPropagation();
}

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

// UnBind:
$(element).off('click', DoPrevent);
Atara
fonte
A maneira como funcionou para mim foi: $ (document) .off ('touchmove'); $ (document) .on ('touchmove', function () {return true;});
Rogervila
9

em alguns casos *, você pode inicialmente em return falsevez de e.preventDefault(), e quando desejar restaurar o padrão para return true.

* Significado quando você não se importa a subida do evento e você não usar o e.stopPropagation()juntamente come.preventDefault()

Veja também pergunta semelhante (também na pilha Overflow)

ou, no caso da caixa de seleção, você pode ter algo como:

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

Você pode restaurar a ação padrão (se for uma sequência HREF) fazendo o seguinte:

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

crmpicco
fonte
2
as idéias estavam corretas, mas o código pronto para uso não funcionou para mim (a menos que seja apenas uma alteração de sintaxe no jquery). Eu usei: window.location = $ (this) .attr ('href');
Modika
3

se é um link então $(this).unbind("click"); reativaria o clique no link e o comportamento padrão seria restaurado.

Eu criei uma demo JS violino de demonstração para demonstrar como isso funciona:

Aqui está o código do violino 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>
Rahul Gupta
fonte
2

Teste este código, acho que resolva seu problema:

event.stopPropagation();

Referência

Alireza MH
fonte
você precisa stopPropagation em um manipulador que ocorre antes do manipulador que impede o padrão. Você pode fazer isso no capturePhase se seu outro manipulador estiver registrado na fase de bolha.
Vitim.us 14/03
2

A melhor maneira de fazer isso usando o espaço para nome. É uma maneira segura e protegida. Aqui .rb é o espaço para nome que garante que a função unbind funcione nesse keydown específico, mas não em outros.

$(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

Rajkumar Bansal
fonte
1

Desativar:

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

Habilitar:

document.ontouchstart = function(e){ return true; }
Brynner Ferreira
fonte
1

O método preventDefault () da interface Event indica ao agente do usuário que, se o evento não for tratado explicitamente, sua ação padrão não deve ser tomada como normalmente. O evento continua a se propagar como de costume, a menos que um de seus ouvintes de evento chame stopPropagation () ou stopImmediatePropagation (), um dos quais finaliza a propagação de uma só vez.

Chamar preventDefault () durante qualquer estágio do fluxo de eventos cancela o evento, significando que qualquer ação padrão normalmente executada pela implementação como resultado do evento não ocorrerá.

Você pode usar Event.cancelable para verificar se o evento é cancelável. Chamar preventDefault () para um evento não cancelável não tem efeito.

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.
    }
}
João Victor Palmeira
fonte
0

Eu tive um problema em que precisava da ação padrão somente após a conclusão de alguma ação personalizada (ativar os campos de entrada desativados em um formulário). Embrulhei a ação padrão (submit ()) em uma função recursiva própria (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()});
Gyula
fonte
1
Nota geral: Embora alguns codificadores considerem if (predef == true)mais explícito, você está adicionando 7 caracteres ao seu código JS sem motivo. if (prevdef)é tão legível. Além disso, você adicionou um manipulador de eventos anônimos redundantes quando .click(dosubmit)faz a mesma coisa .click(function(){dosubmit()})que nenhum parâmetro é passado.
Gone Coding
0

Use um booleano:

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

Eu uso isso em um aplicativo Web progressivo para impedir a rolagem / zoom em algumas 'páginas' enquanto permite outras.

TênisVisuals
fonte
0

Você pode definir para formar 2 classes. Depois de definir seu script JS para um deles, quando você deseja desabilitá-lo, basta excluir a classe com script vinculado deste formulário.

HTML:

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

JS

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

});
Dumitru Boaghi
fonte
-3
$('#my_elementtt').click(function(event){
    trigger('click');
});
T.Todua
fonte
-10

Não sei ao certo o que você quer dizer: mas aqui está uma solução para um problema semelhante (e possivelmente o mesmo) ...

Costumo usar preventDefault () para interceptar itens. No entanto: não é o único método de interceptação ... muitas vezes você pode apenas querer uma "pergunta" após a qual o comportamento continua como antes ou para. Em um caso recente, usei a seguinte solução:

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

Basicamente, o "impedir padrão" deve interceptar e fazer outra coisa: o "confirmar" foi projetado para uso em ... bem - confirmando!

elb98rm
fonte