Mam następujący kod:
function someMethod()
{
$(obj).click(function {});
}
someMethod jest wywoływana dwukrotnie, a zatem zdarzenie click jest dwukrotnie wiązane. Jak mogę sprawić, by to związało tylko raz?
Mam następujący kod:
function someMethod()
{
$(obj).click(function {});
}
someMethod jest wywoływana dwukrotnie, a zatem zdarzenie click jest dwukrotnie wiązane. Jak mogę sprawić, by to związało tylko raz?
Odpowiedzi:
Jeśli możesz to zastosować, prawdopodobnie zechcesz rzucić okiem na event.preventDefault i event.stopPropagation LUB za każdym razem rozpinać i wiązać, w ramach Twojej metody, takiej jak
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Oprócz odpowiedzi pna możesz pomyśleć o utworzeniu przestrzeni nazw wydarzenia, aby nie omijać przypadkowo odłączania wszystkich zdarzeń kliknięcia.
function someMethod () {
$ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {});
}
$(obj).off()i $(obj).on(). W przeciwnym razie przestrzeń nazw pomogła i to zadziałało. Dziękuję Ci!
Nie ma wbudowanej metody określającej, czy ta konkretna funkcja została już powiązana. Do obiektu można przypisać wiele funkcji kliknięcia. Na przykład:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
jeśli wykonasz powyższe czynności, gdy obiekt zostanie kliknięty, pojawi się ostrzeżenie „cześć”, a następnie „żegnaj”. Aby upewnić się, że tylko jedna funkcja jest powiązana ze zdarzeniem kliknięcia, odłącz moduł obsługi zdarzenia kliknięcia, a następnie powiąż żądaną funkcję w następujący sposób:
$(obj).unbind('click').bind('click', function(){... });
Oczywistym rozwiązaniem jest nie dzwonienie someMethod()dwa razy. Jeśli nie możesz tego naprawić, możesz zachować zmienną stanu, aby wiązała się tylko raz w ten sposób:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Uwaga: to używa właściwości samej funkcji zamiast wprowadzania zmiennej globalnej, aby śledzić, czy została powiązana. Możesz również użyć właściwości na samym obiekcie.
Możesz zobaczyć, jak działa tutaj: http://jsfiddle.net/jfriend00/VHkxu/ .
Lub użyj funkcji one () jQuery, która jest podobna do on (), ale uruchamia zdarzenie tylko raz, nawet jeśli powiążesz je wiele razy.
jQuery sprawia, że wywołanie niektórych funkcji jest możliwe tylko raz:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noopjest tylko o jeden znak krótszy niż function(){}, więc głupio jest mówić, że „pomaga”, po prostu udostępnia pustą funkcję. Oto przykład tego rozwiązania ogólnego, który nie jest var fn = function(){ fn = function(){}; do stuff; };
$zamiast tego
To jest sugestia, ponieważ nie znam twojej logiki. Może lub nie zadziała dla Ciebie.
Spróbuj połączyć funkcje live () jquery i one (), aby uzyskać lepszy wynik niż ponowne wiązanie zdarzeń.
Specjalne przypadki działają, gdy masz 2 elementy DOM (nadrzędny i podrzędny). Funkcja Live () w węźle nadrzędnym zapewnia wywołanie zdarzenia, a następnie wywołuje metodę one (), aby dynamicznie zarejestrować zdarzenie, które zostanie wykonane tylko raz. (zapewnia to podobną funkcjonalność jak ponowne wiązania).
One()funkcja działała, chromeale nie działała safariw Mac.
Możesz dodać klasę css do powiązanych elementów, a następnie je odfiltrować:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Ta metoda może być również używana dla wtyczek:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
ale prawdopodobnie sprawdziłbym, dlaczego tak się dzieje; jest wywoływany dwa razy, zanim wykonam jakieś obejście.
boundjest dołączone someMethod()zamiast zanieczyszczać globalną przestrzeń nazw.
Możesz użyć tej funkcji rozszerzenia 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);
}
};
Zamiast tego robić
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Zrób to
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Teraz, kiedy mam wokół tego funkcję
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
I nazywam to wiele razy
addBtnHandler();
addBtnHandler();
addBtnHandler();
Robi to tylko raz.
Zauważ, że rozszerzenie działa, sprawdzając zarówno uid, jak i type. Oznacza to, że możesz wiązać różne typy programów obsługi z tym samym UID, możesz tego chcieć lub nie. Aby to zmienić, edytuj.
var dataStr = type+"-handler-"+uid;
Coś w rodzaju
var dataStr = "handler-"+uid;
Próbowałem też użyć metody włączania i wyłączania jquery do powiązania zdarzenia tylko raz z elementem dom, który jeszcze nie istnieje lub element dom nie został jeszcze utworzony.
$('.select').off('event').on('event', 'selector', function(e){ // });
Ten kod nie działał poprawnie
Natknąłem się na bardzo lukratywną metodę, którą jest metoda „jedna”. Jest to bardzo przydatne, gdy chcesz powiązać wydarzenie tylko raz.
Dokument można znaleźć tutaj http://api.jquery.com/one/
Jest to to samo, co metoda „włączona”, ale różni się jej zachowaniem i nie pozwala na trzymanie się zdarzenia dla wielu selektorów.
$('body').one('click', 'selector', function(){ // do your stuff here });
Można to osiągnąć z czystym JS, używając addEventListener sposób i jego raz opcję
target.addEventListener('click', handler, {once: true});