Comment dissocier un écouteur qui appelle event.preventDefault () (en utilisant jQuery)?

128

jquery toggle appelle preventDefault () par défaut, donc les valeurs par défaut ne fonctionnent pas. vous ne pouvez pas cliquer sur une case à cocher, vous ne pouvez pas cliquer sur un lien, etc.

est-il possible de restaurer le gestionnaire par défaut?

Stijn de Witt
la source
Pouvez-vous donner un exemple de code?
Jojo
4
La question dans le titre est fantastique! Dommage que la question réelle ne soit pas ... J'espérais trouver ici la réponse à la question de savoir comment (si possible) nous pouvons «annuler» l'effet d'une preventDefaultfois qu'il a été appelé. Actuellement, cette question est en fait «comment dissocier un écouteur d'événement avec jQuery?».
Stijn de Witt

Réponses:

80

Dans mon cas:

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

$('#some_link').unbind('click'); a fonctionné comme la seule méthode pour restaurer l'action par défaut.

Comme vu ici: https://stackoverflow.com/a/1673570/211514

Klaus
la source
2
Si cet élément a un autre gestionnaire de clic, vous dissociez tous les événements attachés, non seulement le gestionnaire empêché ...
Aure77
56

C'est assez simple

Supposons que vous fassiez quelque chose comme

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

maintenant, pour revenir à la situation d'origine, procédez comme suit ...

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

À partir de ce site Web .

foxybagga
la source
Cette solution ne fonctionne pas après $ ('# a_link'). Click (function (e) {e.preventDefault ();}); utiliser la fonction de détachement.
Denis Makarskiy le
2
Le lien que vous avez fourni est rompu.
Empilé le
16

Il n'est pas possible de restaurer un preventDefault()mais ce que vous pouvez faire est de le tromper :)

<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 vous souhaitez aller plus loin, vous pouvez même utiliser le bouton de déclenchement pour déclencher un événement.

Val
la source
Je suis presque sûr que c'est le cas - je l'ai fait récemment sur un design. Au début, en cliquant sur un bouton, j'ai empêché le défilement dans un iPhone en ajoutant e.preventDefault à l'événement on touchmove, puis une fois l'animation terminée, je suis retourné true et cela a fonctionné comme un charme.
foxybagga
11
function DoPrevent(e) {
  e.preventDefault();
  e.stopPropagation();
}

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

// UnBind:
$(element).off('click', DoPrevent);
Atara
la source
La façon dont cela fonctionnait pour moi était: $ (document) .off ('touchmove'); $ (document) .on ('touchmove', function () {return true;});
rogervila
9

dans certains cas * vous pouvez initialement return falseau lieu de e.preventDefault(), puis lorsque vous souhaitez restaurer la valeur par défautreturn true .

* Cela signifie que lorsque l'événement bouillonne ne vous dérange pas et que vous n'utilisez pas le e.stopPropagation()avece.preventDefault()

Voir également la question similaire (également dans le débordement de pile)

ou dans le cas de la case à cocher, vous pouvez avoir quelque chose comme:

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

Vous pouvez restaurer l'action par défaut (s'il s'agit d'un suivi HREF) en procédant comme suit:

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

crmpicco
la source
2
les idées avaient raison mais le code prêt à l'emploi ne fonctionnait pas pour moi (à moins que ce ne soit juste un changement de syntaxe dans jquery) j'ai utilisé: window.location = $ (this) .attr ('href');
Modika
3

s'il s'agit d'un lien $(this).unbind("click");, réactiverait le clic sur le lien et le comportement par défaut serait restauré.

J'ai créé une démonstration de violon JS pour montrer comment cela fonctionne:

Voici le code du violon 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
la source
2

Testez ce code, je pense résoudre votre problème:

event.stopPropagation();

Référence

Alireza MH
la source
vous devez stopPropagation sur un gestionnaire qui se produit avant le gestionnaire qui empêche default. Vous pouvez le faire sur la capturePhase si votre autre gestionnaire est inscrit sur la phase de bulle.
Vitim.us
2

La meilleure façon de faire cela en utilisant l'espace de noms. C'est un moyen sûr et sécurisé. Ici .rb est l'espace de noms qui garantit que la fonction de détachement fonctionne sur ce keydown particulier mais pas sur d'autres.

$(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
la source
1

Désactiver:

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

Activer:

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

La méthode preventDefault () de l'interface Event indique à l'agent utilisateur que si l'événement n'est pas traité explicitement, son action par défaut ne doit pas être prise comme elle le serait normalement. L'événement continue à se propager comme d'habitude, sauf si l'un de ses écouteurs d'événement appelle stopPropagation () ou stopImmediatePropagation (), l'un ou l'autre mettant fin à la propagation en même temps.

L'appel de preventDefault () à n'importe quelle étape du flux d'événements annule l'événement, ce qui signifie que toute action par défaut normalement prise par l'implémentation à la suite de l'événement ne se produira pas.

Vous pouvez utiliser Event.cancelable pour vérifier si l'événement est annulable. L'appel de preventDefault () pour un événement non annulable n'a aucun effet.

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
la source
0

J'ai eu un problème où j'avais besoin de l'action par défaut uniquement après la fin d'une action personnalisée (activer les champs de saisie autrement désactivés sur un formulaire). J'ai encapsulé l'action par défaut (submit ()) dans une propre fonction récursive (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
la source
1
Remarque générale: bien que certains codeurs pensent que if (predef == true)c'est plus explicite, vous ajoutez 7 caractères à votre code JS sans raison. if (prevdef)est tout aussi lisible. En outre, vous avez ajouté un gestionnaire d'événements anonyme redondant lorsque .click(dosubmit)fait la même chose que .click(function(){dosubmit()})si aucun paramètre n'est passé.
Fini le codage
0

Utilisez un booléen:

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

J'utilise ceci dans une application Web progressive pour empêcher le défilement / zoom sur certaines «pages» tout en autorisant d'autres.

TennisVisuels
la source
0

Vous pouvez définir pour former 2 classes. Après avoir défini votre script JS sur l'un d'entre eux, lorsque vous souhaitez désactiver votre script, vous supprimez simplement la classe avec le script lié de ce formulaire.

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
la source
-3
$('#my_elementtt').click(function(event){
    trigger('click');
});
T.Todua
la source
-10

Je ne sais pas ce que vous voulez dire: mais voici une solution pour un problème similaire (et peut-être le même) ...

J'utilise souvent preventDefault () pour intercepter des éléments. Cependant: ce n'est pas la seule méthode d'interception ... souvent vous voudrez peut-être juste une "question" à la suite de laquelle le comportement continue comme avant ou s'arrête. Dans un cas récent, j'ai utilisé la solution suivante:

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

Fondamentalement, le "prévenir par défaut" est destiné à intercepter et à faire autre chose: le "confirm" est conçu pour être utilisé dans ... eh bien - confirmer!

elb98rm
la source