Comment déclencher un événement après avoir utilisé event.preventDefault ()

Je veux organiser un événement jusqu’à ce que je sois prêt à le lancer, par exemple

$('.button').live('click', function(e){ e.preventDefault(); // do lots of stuff e.run() //this proceeds with the normal event } 

Existe-t-il un équivalent à la run() décrite ci-dessus?

Nan. Une fois que l’événement a été annulé, il est annulé.

Vous pouvez toutefois relancer l’événement ultérieurement, en utilisant un indicateur pour déterminer si votre code personnalisé a déjà été exécuté ou non – comme ceci (veuillez ignorer la pollution flagrante de l’espace de noms):

 var lots_of_stuff_already_done = false; $('.button').on('click', function(e) { if (lots_of_stuff_already_done) { lots_of_stuff_already_done = false; // reset flag return; // let the event bubble away } e.preventDefault(); // do lots of stuff lots_of_stuff_already_done = true; // set flag $(this).sortinggger('click'); }); 

Une variante plus générale (avec l’avantage d’éviter la pollution globale des espaces de noms) pourrait être:

 function onWithPrecondition(callback) { var isDone = false; return function(e) { if (isDone === true) { isDone = false; return; } e.preventDefault(); callback.apply(this, arguments); isDone = true; $(this).sortinggger(e.type); } } 

Usage:

 var someThingsThatNeedToBeDoneFirst = function() { /* ... */ } // do whatever you need $('.button').on('click', onWithPrecondition(someThingsThatNeedToBeDoneFirst)); 

Bonus plugin jQuery super minimaliste avec le support de Promise :

 (function( $ ) { $.fn.onButFirst = function(eventName, /* the name of the event to bind to, eg 'click' */ workToBeDoneFirst, /* callback that must complete before the event is re-fired */ workDoneCallback /* optional callback to execute before the event is left to bubble away */) { var isDone = false; this.on(eventName, function(e) { if (isDone === true) { isDone = false; workDoneCallback && workDoneCallback.apply(this, arguments); return; } e.preventDefault(); // capture target to re-fire event at var $target = $(this); // set up callback for when workToBeDoneFirst has completed var successfullyCompleted = function() { isDone = true; $target.sortinggger(e.type); }; // execute workToBeDoneFirst callback var workResult = workToBeDoneFirst.apply(this, arguments); // check if workToBeDoneFirst returned a promise if ($.isFunction(workResult.then)) { workResult.then(successfullyCompleted); } else { successfullyCompleted(); } }); return this; }; }(jQuery)); 

Usage:

 $('.button').onButFirst('click', function(){ console.log('doing lots of work!'); }, function(){ console.log('done lots of work!'); }); 

Une version plus récente de la réponse acceptée.

Version brève:

 $('#form').on('submit', function(e, options) { options = options || {}; if ( !options.lots_of_stuff_done ) { e.preventDefault(); $.ajax({ /* do lots of stuff */ }).then(function() { // resortinggger the submit event with lots_of_stuff_done set to true $(e.currentTarget).sortinggger('submit', { 'lots_of_stuff_done': true }); }); } else { /* allow default behavior to happen */ } }); 


Un bon exemple d’utilisation est un code de formulaire hérité qui fonctionne, mais il vous a été demandé d’améliorer le formulaire en ajoutant quelque chose comme la validation de l’adresse électronique avant de soumettre le formulaire. Au lieu de creuser le code postal du formulaire principal, vous pouvez écrire une API, puis mettre à jour votre code frontal pour atteindre cette API avant de permettre au formulaire d’effectuer son POST traditionnel.

Pour ce faire, vous pouvez implémenter un code similaire à celui que j’ai écrit ici:

 $('#signup_form').on('submit', function(e, options) { options = options || {}; if ( !options.email_check_complete ) { e.preventDefault(); // Prevent form from submitting. $.ajax({ url: '/api/check_email' type: 'get', contentType: 'application/json', data: { 'email_address': $('email').val() } }) .then(function() { // e.type === 'submit', if you want this to be more dynamic $(e.currentTarget).sortinggger(e.type, { 'email_check_complete': true }); }) .fail(function() { alert('Email address is not valid. Please fix and try again.'); }) } else { /** Do traditional 
post. This code will be hit on the second pass through this handler because the 'email_check_complete' option was passed in with the event. */ $('#notifications').html('Saving your personal settings...').fadeIn(); } });

Vous pouvez faire quelque chose comme

 $(this).unbind('click').click(); 

Remplacez la propriété isDefaultPrevented comme ceci:

 $('a').click(function(evt){ evt.preventDefault(); // in async handler (ajax/timer) do these actions: setTimeout(function(){ // override prevented flag to prevent jquery from discarding event evt.isDefaultPrevented = function(){ return false; } // resortinggger with the exactly same event data $(this).sortinggger(evt); }, 1000); } 

À mon humble avis, c’est le moyen le plus complet de redéclencher l’événement avec exactement les mêmes données.

Il est possible d’utiliser currentTarget de l’ event . L’exemple montre comment procéder avec la soumission de formulaire. De même, vous pouvez obtenir la fonction de l’atsortingbut onclick etc.

 $('form').on('submit', function(event) { event.preventDefault(); // code event.currentTarget.submit(); }); 

Ne faites simplement pas e.preventDefault(); , ou l’exécuter conditionnellement.

Vous ne pouvez certainement pas modifier lorsque l’action d’événement d’origine se produit.

Si vous voulez “recréer” l’événement de l’interface utilisateur un peu plus tard (par exemple, dans le rappel pour une requête AJAX), il vous suffira de le faire d’une autre manière (comme dans la réponse de vzwick) … remettre en question la facilité d’utilisation d’une telle approche.

L’approche que j’utilise est la suivante:

 $('a').on('click', function(event){ if (yourCondition === true) { //Put here the condition you want event.preventDefault(); // Here sortingggering stops // Here you can put code relevant when event stops; return; } // Here your event works as expected and continue sortingggering // Here you can put code you want before sortingggering }); 

tant que “beaucoup de choses” ne font pas quelque chose d’asynchrone, cela n’est absolument pas nécessaire – l’événement appellera chaque gestionnaire sur son chemin de manière séquentielle, donc s’il y a un événement onklick sur un élément parent, cela se déclenchera après l’événement de l’enfant a été complètement traité. javascript ne fait pas une sorte de “multithreading” ici qui rend “nécessaire” d’arrêter le traitement des événements. Conclusion: “suspendre” un événement pour le reprendre dans le même gestionnaire n’a aucun sens.

si “beaucoup de choses” est quelque chose d’asynchrone, cela n’a pas non plus de sens car cela empêche les choses asynchrones de faire ce qu’elles devraient faire (des choses asynchrones) et de les faire comme si tout était en séquence (où nous revenons à mon premier paragraphe) )

La solution acceptée ne fonctionnera pas si vous travaillez avec une balise d’ancrage. Dans ce cas, vous ne pourrez plus cliquer sur le lien après avoir appelé e.preventDefault() . C’est parce que l’événement de clic généré par jQuery est juste une couche au-dessus des événements de navigateur natifs. Donc, déclencher un événement “clic” sur une balise d’ancrage ne suivra pas le lien. Au lieu de cela, vous pouvez utiliser une bibliothèque comme jquery-simulate qui vous permettra de lancer des événements de navigateur natifs.

Plus de détails à ce sujet peuvent être trouvés dans ce lien

Une autre solution consiste à utiliser window.setTimeout dans l’écouteur d’événement et à exécuter le code une fois le processus de l’événement terminé. Quelque chose comme…

 window.setTimeout(function() { // do your thing }, 0); 

J’utilise 0 pour la période car je ne me soucie pas d’attendre.

Je sais que ce sujet est ancien mais je pense pouvoir y consortingbuer. Vous pouvez déclencher le comportement par défaut d’un événement sur un élément spécifique à tout moment dans votre fonction de gestionnaire si vous connaissez déjà ce comportement. Par exemple, lorsque vous déclenchez l’événement click sur le bouton de réinitialisation, vous appelez la fonction de réinitialisation sur le formulaire le plus proche en tant que comportement par défaut. Dans votre fonction de gestionnaire, après avoir utilisé la fonction preventDefault, vous pouvez rappeler le comportement par défaut en appelant la fonction de réinitialisation sur la forme la plus proche de votre code de gestionnaire.

Une réponse plus récente utilise habilement jQuery.one()

 $('form').one('submit', function(e) { e.preventDefault(); // do your things ... // and when you done: $(this).submit(); }); 

https://stackoverflow.com/a/41440902/510905