Ho il codice seguente:
function someMethod()
{
$(obj).click(function {});
}
someMethod viene chiamato due volte e quindi l'evento click viene associato due volte. Come posso farlo legare solo una volta?
Ho il codice seguente:
function someMethod()
{
$(obj).click(function {});
}
someMethod viene chiamato due volte e quindi l'evento click viene associato due volte. Come posso farlo legare solo una volta?
Risposte:
Se puoi applicarlo, probabilmente vorrai dare un'occhiata a event.preventDefault e event.stopPropagation OPPURE separare e legare ogni volta, all'interno del tuo metodo come
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Oltre alla risposta di pna, potresti pensare allo spazio dei nomi per il tuo evento in modo da non andare in giro a svincolare accidentalmente tutti gli eventi di clic.
function someMethod () {
$ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {});
}
$(obj).off()e $(obj).on()rispettivamente. Altrimenti, lo spazio dei nomi ha aiutato e ha funzionato. Grazie!
Non esiste un metodo integrato per determinare se hai già associato questa particolare funzione. È possibile associare più funzioni di clic a un oggetto. Per esempio:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
se si esegue quanto sopra quando si fa clic sull'oggetto, verrà avvisato ciao e poi arrivederci. Per assicurarsi che solo una funzione sia associata all'evento clic, svincolare il gestore dell'evento clic, quindi associare la funzione desiderata in questo modo:
$(obj).unbind('click').bind('click', function(){... });
La soluzione ovvia è non chiamare someMethod()due volte. Se non riesci a risolverlo, puoi mantenere una variabile di stato in modo che si leghi solo una volta in questo modo:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Nota: questo utilizza una proprietà della funzione stessa piuttosto che introdurre una variabile globale per tenere traccia se è stata associata. Puoi anche usare una proprietà sull'oggetto stesso.
Puoi vederlo funzionare qui: http://jsfiddle.net/jfriend00/VHkxu/ .
Oppure usa la funzione one () di jQuery che è simile a on () ma attiva l'evento solo una volta, anche se lo leghi più volte.
jQuery rende possibile chiamare alcune funzioni solo una volta piuttosto semplice:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noopè solo un carattere più corto di function(){}, quindi è un po 'sciocco dire che "aiuta" qui, fornendo solo una funzione vuota. Ecco un esempio non di metodo jQuery di questa soluzione generale:var fn = function(){ fn = function(){}; do stuff; };
$posto
Questo è un suggerimento poiché non conosco la tua logica. Può o non può funzionare per te.
Prova a combinare le funzioni jquery live () e one () per ottenere un risultato migliore rispetto ai rebind di eventi.
I casi speciali funzionano quando hai 2 elementi DOM (genitore e figlio). Live () sul nodo genitore si assicura che l'evento venga richiamato, quindi chiama one () per registrare dinamicamente l'evento che verrebbe eseguito solo una volta. (questo fornisce funzionalità simili come i rebind).
One()la funzione ha lavorato in chrome, ma non ha funzionato in safaria Mac.
Puoi aggiungere una classe CSS agli elementi associati e quindi filtrarli:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Questo metodo può essere utilizzato anche per i plugin:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
ma probabilmente esaminerei il motivo per cui viene chiamato due volte prima di fare una sorta di soluzione alternativa.
boundè collegato someMethod()invece di inquinare lo spazio dei nomi globale.
È possibile utilizzare questa funzione di estensione 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);
}
};
Invece di fare questo
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Lo fai
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Ora, quando ho una funzione intorno ad esso
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
E lo chiamo più volte
addBtnHandler();
addBtnHandler();
addBtnHandler();
Lo fa solo una volta.
Si noti che l'estensione funziona controllando sia uid che type. Ciò significa che puoi associare diversi tipi di gestori con lo stesso uid, potresti volerlo o meno. Per cambiarlo modifica.
var dataStr = type+"-handler-"+uid;
Con qualcosa di simile
var dataStr = "handler-"+uid;
Stavo anche cercando di utilizzare il metodo off e on di jquery per associare l'evento solo una volta con l'elemento dom che non esiste ancora o l'elemento dom non è ancora stato creato.
$('.select').off('event').on('event', 'selector', function(e){ // });
Questo codice non funzionava correttamente
Mi sono imbattuto in un metodo molto redditizio che è il metodo "uno". È molto utile quando vuoi associare un evento solo una volta.
Puoi trovare il documento qui http://api.jquery.com/one/
Questo è lo stesso del metodo "on" ma diverso per il comportamento di non rimanere fedeli all'evento per più selettori.
$('body').one('click', 'selector', function(){ // do your stuff here });
Puoi ottenere questo risultato con JS puro, usando il metodo addEventListener e la sua opzione once
target.addEventListener('click', handler, {once: true});