J'ai résolu ce problème en
- placer un écouteur d'événements sur un élément parent
- supprimer la classe du lien UNIQUEMENT lorsque l'utilisateur confirme
-
en recliquant sur le lien après avoir supprimé la classe.
function async() {
var dfd = $.Deferred();
// simulate async
setTimeout(function () {
if (confirm('Stackoverflow FTW')) {
dfd.resolve();
} else {
dfd.reject();
}
}, 0);
return dfd.promise();
};
$('.container').on('click', '.another-page', function (e) {
e.stopPropagation();
e.preventDefault();
async().done(function () {
$(e.currentTarget).removeClass('another-page').click();
});
});
$('body').on('click', function (e) {
alert('navigating somewhere else woot!')
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<a href="#" class="another-page">Somewhere else</a>
</div>
La raison pour laquelle j'ai ajouté l'écouteur d'événement au parent et non au lien lui-même est que la méthode jQuery on
sera lié à l'élément jusqu'à ce qu'il en soit décidé autrement. Ainsi, même si l'élément n'a pas la classe another-page
il y a toujours l'écouteur d'événement attaché, donc vous devez tirer parti de event delegation
pour résoudre ce problème.
GOTCHAS Si vous avez besoin de demander à l'utilisateur CHAQUE fois qu'il clique sur un lien, vous devrez ajouter un deuxième écouteur pour lire les données de l'utilisateur. another-page
sur le lien, c'est à dire :
$('body').on('click', function (e) {
$(e.currentTarget).addClass('another-page');
});
note complémentaire vous pouvez également supprimer l'écouteur d'événement sur container
si l'utilisateur accepte, si vous faites cela, assurez-vous d'utiliser namespace
car il peut y avoir d'autres auditeurs sur le conteneur que vous pourriez supprimer par inadvertance. voir https://api.jquery.com/event.namespace/ pour plus de détails.
1 votes
Avez-vous essayé
$this.trigger(e);
( éditer qui aurait besoin d'un drapeau s'il fonctionnait) ou$this.parent().trigger(e)
(dans le callback), où$this
se réfère aux éléments cliqués ?0 votes
@FelixKling Cela ne fonctionnera pas car
e.preventDefault(); e.stopPropogation();
a envoyé des drapeaux sur e. S'il existait un moyen d'envoyer une copie de e à e2, je pourrais appeler quelque chose du genree.handler(e2)
ce qui, à mon avis, devrait fonctionner.0 votes
Je me suis dit que jQuery était peut-être assez intelligent pour réinitialiser les drapeaux lorsqu'ils sont transmis à
trigger
...0 votes
@FelixKling bon appel, mais je viens de vérifier le code - pas de chance.
0 votes
@FelixKling : Je viens d'essayer votre
.parent()
en utilisant l'objet événementiel d'origine, et cela semble fonctionner correctement. jsfiddle.net/vTzDM Je me demande pourquoi cela ne fonctionnait pas pour George.0 votes
@_._ : Je suppose qu'il a essayé
.trigger(e)
(qui ne fonctionne pas). Dans votre cas, l'objet événement est simplement transmis comme paramètre au gestionnaire d'événement, mais ses propriétés ne sont pas utilisées pour le nouvel objet événement, de sorte qu'il ne semble pas nécessaire de le transmettre. Je ne sais pas si le PO en a besoin ou non..parent().click()
semble être une bonne alternative, mais cela dépend de ce que font les autres gestionnaires d'événements dans la hiérarchie. Merci d'avoir essayé :)0 votes
@FelixKling : Ah, vous avez raison. Je me suis également trompé dans ma réponse.
0 votes
@_._ : Je pense que vos deuxième et troisième suggestions sont bonnes.
1 votes
@FelixKling : Merci, mais si l'objet original de l'événement n'est pas nécessaire, alors
.parent().click()
serait de loin la plus simple.