¿Cómo desvincular un escucha que está llamando a event.preventDefault () (usando jQuery)?


128

jquery alterna las llamadas preventDefault () de forma predeterminada, por lo que los valores predeterminados no funcionan. no puede hacer clic en una casilla de verificación, no puede hacer clic en un enlace, etc.

¿Es posible restaurar el controlador predeterminado?


¿Puedes dar algún código de ejemplo?
Jojo el

44
¡La pregunta en el título es fantástica! Lástima que la pregunta real no sea ... esperaba encontrar aquí, la respuesta a cómo (si es posible) podemos 'desarmar' el efecto preventDefaultdespués de haber sido llamado. Actualmente, esta pregunta es en realidad '¿cómo desvinculo un oyente de eventos con jQuery?'.
Stijn de Witt

Respuestas:


80

En mi caso:

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

$('#some_link').unbind('click'); funcionó como el único método para restaurar la acción predeterminada.

Como se ve aquí: https://stackoverflow.com/a/1673570/211514


2
Si este elemento tiene otro controlador de clics, desvinculará todos los eventos adjuntos, no solo
evitará el

56

Es bastante simple

Supongamos que haces algo como

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

ahora para volver a la situación original, haga lo siguiente ...

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

De este sitio web .


Esta solución no funciona después de $ ('# a_link'). Click (function (e) {e.preventDefault ();}); utilizar la función de desvinculación
Denis Makarskiy

2
El enlace que proporcionó está roto.
Apilado el

16

No es posible restaurar un preventDefault()pero lo que puedes hacer es engañarlo :)

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

Si desea ir un paso más allá, incluso puede usar el botón de activación para activar un evento.


Estoy bastante seguro de que es así: hice esto recientemente en un diseño. Al principio, al hacer clic en un botón, evité el desplazamiento en un iPhone agregando e.preventDefault al evento touchmove y luego, una vez que se realizó la animación, volví verdadero y funcionó de maravilla.
foxybagga

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

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

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

La forma en que funcionó para mí fue: $ (document) .off ('touchmove'); $ (document) .on ('touchmove', function () {return true;});
rogervila

9

en algunos casos * puede inicialmente en return falselugar de e.preventDefault(), luego cuando quiera restaurar el valor predeterminado return true.

* Es decir, cuando no te importa que el evento burbujee y no lo uses e.stopPropagation()junto cone.preventDefault()

Vea también una pregunta similar (también en el desbordamiento de pila)

o en el caso de la casilla de verificación puede tener algo como:

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

9

Puede restaurar la acción predeterminada (si es un seguimiento HREF) haciendo esto:

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


2
las ideas eran correctas, pero el código original no funcionó para mí (a menos que sea solo un cambio de sintaxis en jquery) utilicé: window.location = $ (this) .attr ('href');
Modika

3

si es un enlace, $(this).unbind("click");volvería a habilitar el clic del enlace y se restablecería el comportamiento predeterminado.

He creado una demostración de JS Fiddle para demostrar cómo funciona esto:

Aquí está el código del violín 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

Prueba este código, creo que resuelve tu problema:

event.stopPropagation();

Referencia


debe detener la propagación en un controlador que se produce antes del controlador que impide el valor predeterminado. Puede hacer esto en capturePhase si su otro controlador está registrado en la fase de burbuja.
Vitim.us

2

La mejor manera de hacer esto usando el espacio de nombres. Es una forma segura y protegida. Aquí .rb es el espacio de nombres que garantiza que la función de desvinculación funcione en ese keydown particular pero no en otros.

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

Inhabilitar:

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

Habilitar:

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

1

El método preventDefault () de la interfaz de eventos le dice al agente de usuario que si el evento no se maneja explícitamente, su acción predeterminada no debe tomarse como lo haría normalmente. El evento continúa propagándose como de costumbre, a menos que uno de sus oyentes de eventos llame a stopPropagation () o stopImmediatePropagation (), cualquiera de los cuales finaliza la propagación a la vez.

Si se llama a preventDefault () durante cualquier etapa del flujo de eventos, se cancela el evento, lo que significa que no se producirá ninguna acción predeterminada que normalmente tome la implementación como resultado del evento.

Puede usar Event.cancelable para verificar si el evento es cancelable. Llamar a preventDefault () para un evento no cancelable no tiene ningún efecto.

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

Tuve un problema en el que necesitaba la acción predeterminada solo después de que alguna acción personalizada (habilitar campos de entrada deshabilitados en un formulario) hubiera concluido. Envolví la acción predeterminada (submit ()) en una función propia y recursiva (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
Nota general: Si bien algunos codificadores consideran que if (predef == true)es más explícito, está agregando 7 caracteres a su código JS sin ningún motivo. if (prevdef)es igual de legible. Además, ha agregado un controlador de eventos anónimo redundante cuando .click(dosubmit)hace lo mismo que .click(function(){dosubmit()})no se pasan parámetros.
Gone Coding

0

Use un booleano:

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

Lo uso en una aplicación web progresiva para evitar desplazarse / hacer zoom en algunas 'páginas' y permitir otras.


0

Puede configurar para formar 2 clases. Después de configurar su script JS en uno de ellos, cuando desee deshabilitar su script, simplemente elimine la clase con script enlazado de este formulario.

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

No estoy seguro de que sea lo que quiere decir: pero aquí hay una solución para un problema similar (y posiblemente el mismo) ...

A menudo uso preventDefault () para interceptar elementos. Sin embargo: no es el único método de intercepción ... a menudo es posible que solo desee una "pregunta" sobre qué comportamiento continúa como antes o se detiene. En un caso reciente, utilicé la siguiente solución:

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

Básicamente, el "prevenir incumplimiento" está destinado a interceptar y hacer otra cosa: el "confirmar" está diseñado para usarse en ... bueno, ¡confirmando!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.