J’ai le code suivant:
function someMethod() { $(obj).click(function {}); }
someMethod est appelé deux fois et donc l’événement click est lié deux fois. Comment puis-je le rendre lié une seule fois?
Si vous pouvez l’appliquer, vous voudrez probablement jeter un coup d’oeil à event.preventDefault et event.stopPropagation OU désassembler et lier chaque fois, dans votre méthode comme
function someMethod() { $(obj).off('click').on('click', function(e) { // put your logic in here }); }
En plus de la réponse de pna, vous pouvez penser à nommer votre événement pour ne pas débloquer tous les événements de clic accidentellement.
function someMethod () { $ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {}); }
Il n’y a pas de méthode intégrée pour déterminer si vous avez déjà lié cette fonction particulière. Vous pouvez lier plusieurs fonctions de clic à un object. Par exemple:
$('#id').bind('click', function(){ alert('hello'); }); $('#id').bind('click', function(){ alert('goodbuy'); });
Si vous faites ce qui précède lorsque l’object est cliqué, il alertera bonjour, puis au revoir. Pour vous assurer qu’une seule fonction est liée à l’événement click, désélectionnez le gestionnaire d’événement click, puis liez la fonction souhaitée comme suit:
$(obj).unbind('click').bind('click', function(){... });
La solution évidente consiste à ne pas appeler someMethod()
deux fois. Si vous ne parvenez pas à résoudre ce problème, vous pouvez conserver une variable d’état afin qu’elle ne soit liée qu’une seule fois, comme ceci:
function someMethod() { if (!someMethod.bound) { $(obj).click(function() {}); someMethod.bound = true; } }
Remarque: ceci utilise une propriété de la fonction elle-même plutôt que d’introduire une variable globale pour savoir si elle a été liée. Vous pouvez également utiliser une propriété sur l’object lui-même.
Vous pouvez le voir fonctionner ici: http://jsfiddle.net/jfriend00/VHkxu/ .
Ou utilisez la fonction one () de jQuery qui est similaire à on () mais ne déclenche l’événement qu’une seule fois, même si vous le liez plusieurs fois.
jQuery rend l’appel d’une fonction possible une fois assez simple:
function someMethod() { $(obj).click(function() {}); this.someMethod = $.noop; }
Ceci est une suggestion puisque je ne connais pas votre logique. Peut ou peut ne pas fonctionner pour vous.
Essayer de combiner les fonctions jquery live () et one () vous donnera un meilleur résultat que les rebinds d’événements.
Les cas particuliers fonctionnent lorsque vous avez 2 éléments DOM (parent et enfant). Live () au nœud parent s’assure que l’événement sera appelé, puis appelle one () pour enregistrer dynamicment l’événement qui ne serait exécuté qu’une seule fois. (cela fournit des fonctionnalités similaires, comme les rebinds).
var bound = false; function someMethod() { if(!bound) { $(obj).click(function {}); bound = true; } }
mais je regarderais probablement pourquoi il est appelé deux fois avant de faire une sorte de solution de contournement.
Si vous souhaitez vous lier à l’object une seule fois, vous devez implémenter un indicateur et vous en tenir à cet object.
Par exemple:
if($('#id') && $('#id').data('done') == null)) { $('#id').bind('click', function() { alert('hello'); }); $('#id').data('done', true); }
Vous pouvez append la classe css aux éléments liés puis les filtrer:
function someMethod() { $(obj).not('.click-binded') .click(function {}) .addClass('click-binded'); }
Cette méthode peut également être utilisée pour les plugins:
$(obj).not('.datetimepicker-applied') .datetimepicker() .addClass('datetimepicker-applied');
Vous pouvez utiliser cette fonction d’extension jQuery.
$.fn.once = function (type, fn, uid) { if(uid == undefined) { console.error("Called $.once without uid\n", this, "\n", fn); } var dataStr = type+"-handler-"+uid; if(!this.data(dataStr)) { this.data(dataStr, true); this.on(type, fn); } };
Au lieu de le faire
$("button").on("click", function(){ alert("You Clicked On A Button"); });
Ya faire ça
$("button").once("click", function(){ alert("You Clicked On A Button"); }, "btnHandler");
Maintenant, quand j’ai une fonction autour de lui
function addBtnHandler() { $("button").once("click", function() { alert("You Clicked On A Button"); }, "btnHandler"); }
Et je l’appelle plusieurs fois
addBtnHandler(); addBtnHandler(); addBtnHandler();
Il ne le fait qu’une fois.
Notez que l’extension fonctionne en vérifiant à la fois uid et le type. Cela signifie que vous pouvez lier différents types de gestionnaires avec le même uid, vous pouvez ou non vouloir cela. Pour le modifier, modifiez-le.
var dataStr = type+"-handler-"+uid;
Avec quelque chose comme
var dataStr = "handler-"+uid;
J’essayais également d’utiliser la méthode de jquery off et on pour la liaison d’événement une seule fois avec l’élément dom qui n’existe pas encore ou si l’élément dom n’est pas encore créé.
$('.select').off('event').on('event', 'selector', function(e){ // });
Ce code ne fonctionnait pas correctement
Je suis tombé sur une méthode très lucrative qui est la méthode «un». C’est très utile lorsque vous souhaitez lier un événement une seule fois.
Vous pouvez trouver le document ici http://api.jquery.com/one/
C’est la même chose que la méthode ‘on’ mais différente avec son comportement de ne pas s’en tenir à l’événement pour plusieurs sélecteurs.
$('body').one('click', 'selector', function(){ // do your stuff here });
Vous pouvez réaliser cela avec JS pure, en utilisant la méthode addEventListener et son option unique
target.addEventListener('click', handler, {once: true});