2012-04-20 14 views
5

Czy ktoś może powiedzieć, jak "usunąć" anonimową funkcję? JQUERY jest w stanie to zrobić, ale jak mogę zaimplementować tę Funkcjonalność w moim własnym skrypcie.Rozpięcie anonimowej funkcji

Jest to scenariusz:

Poniższy kod dołączyć „onclick” zdarzenie do Div, które mają „someDivId” jako ID, teraz wen kliknięciu DIV, to pokaz „kliknięcia!”.

var a = document.getElementById('someDivId'); 
bindEvent(a,'click',function(){alert('clicked!');}); 

To wszystko świetnie, problemem jest to, jak „un-dołączyć” funkcji do DIV, czy funkcja jest anonimowa lub jak „un-dołączyć” wszystkie podłączone zdarzenia do „a” Element?

unBind(a,'click'); //Not necessarily the given params, it's just an example. 

Jest to kod dla metody bindEvent:

function bindEvent (el,evtType,fn){ 
    if (el.attachEvent) { 
     el['e'+evtType+fn] = fn; 
     el[evtType+fn] = function(){ 
      fn.call(el,window.event); 
     } 
     el.attachEvent('on'+evtType, el[evtType+fn]); 
    } else { 
     el.addEventListener(evtType, fn, false); 
    } 
} 
+1

Skąd otrzymałeś 'bindEvent()'? Co to robi? – jfriend00

+0

Pytasz o odpowiedź niezwiązaną z jQuery (np. Zwykły javascript)? – jfriend00

+0

@ jfriend00: chce go wdrożyć na własną rękę - np. nie używa jQuery, ale pyta, jak robi to jQuery. – prodigitalson

Odpowiedz

4

Wreszcie, po wielu godzinach prób & błędów znalazłem rozwiązanie, może to nie jest najlepszy i najbardziej wydajny ale ... PRACE! (Testowane na IE9, Firefox 12, Chrome 18)

Najpierw tworzę dwie różne przeglądarki i pomocnicze metody addEvent() i removeEvent(). (Pomysł zaczerpnięty z kodu źródłowego Jquery'ego!)

HELPERS.removeEvent = document.removeEventListener ? 
function(type, handle,el) { 
    if (el.removeEventListener) { 
    //W3C Standard  
    el.removeEventListener(type, handle, true); 
    } 
} : 
function(type, handle,el) { 
    if (el.detachEvent) { 
     //The IE way 
     el.detachEvent('on'+type, el[type+handle]); 
     el[type+handle] = null; 
    } 
}; 

HELPERS.addEvent = document.addEventListener ? 
function(type, handle,el) { 
    if (el.addEventListener) { 
     //W3C Standard 
     el.addEventListener(type, handle, true); 
    } 
} : 
function(type, handle,el) { 
    if (el.attachEvent) { 
     //The IE way 
     el['e'+type+handle] = handle; 
     el[type+handle] = function(){ 
      handle.call(el,window.event); 
     }; 
     el.attachEvent('on'+type, el[type+handle]); 

    } 
} 

Również musimy jakąś „kontener” do przechowywania załączonego zdarzeń do elementów, takich jak to:

HELPERS.EVTS = {}; 

i wreszcie dwa wymagalne i narażone na Metod użytkowników: następnego jeden do dodania zdarzenia (zdarzenia) i powiązania tego zdarzenia z metodą (handler) dla określonego elementu (el).

function bindEvent(event, handler,el) { 

      if(!(el in HELPERS.EVT)) { 
       // HELPERS.EVT stores references to nodes 
       HELPERS.EVT[el] = {}; 
      } 

      if(!(event in HELPERS.EVT[el])) { 
       // each entry contains another entry for each event type 
       HELPERS.EVT[el][event] = []; 
      } 
      // capture reference 
      HELPERS.EVT[el][event].push([handler, true]); 
      //Finally call the aux. Method 
      HELPERS.addEvent(event,handler,el); 

     return; 

    } 

Wreszcie sposób, że un-dołączyć co wcześniej dołączone zdarzeń (Event) w odniesieniu do konkretnego elementu (EL)

function removeAllEvent(event,el) { 

      if(el in HELPERS.EVT) { 
       var handlers = HELPERS.EVT[el]; 
       if(event in handlers) { 
        var eventHandlers = handlers[event]; 
        for(var i = eventHandlers.length; i--;) { 
         var handler = eventHandlers[i]; 
         HELPERS.removeEvent(event,handler[0],el); 

        } 
       } 
      } 

    return; 

    } 

Nawiasem mówiąc, do wywołania tej metody należy wykonać następujące czynności: przechwytywania DOM Węzeł

var a = document.getElementById('some_id'); 

połączenia metoda "bindEvent() z odpowiednimi parametrami.

bindEvent('click',function(){alert('say hi');},a); 

I de-podłączyć go:

removeAllEvent('click',a); 

To wszystko, mam nadzieję, będą przydatne dla kogoś jednego dnia.

+1

Nie jestem pewien, czy linia 'HELPERS.EVT [el]', gdzie 'el' jest odniesieniem do elementu DOM, robi to, co myślisz, że robi. Nazwy właściwości JavaScript [muszą być ciągami] (https://developer.mozilla.org/en/JavaScript/Reference/Operators/Member_Operators#Property_names) i nie jestem pewien, czy istnieje standardowa metoda "toString" dla elementów DOM. W Firefox 11 i IE9 otrzymuję '' [object HTMLDivElement] '' podczas wywoływania 'toString' na elemencie' div'. –

+0

@CheranShunmugavel: Dokładnie. Przy użyciu tego systemu dwa różne elementy "div" pojawią się jako ta sama właściwość w tabeli "HELPERS.EVT". –

2

Osobiście (i wiem, że to nie jest „najlepszy” sposób, gdyż nie wymaga mnie do myślenia o tym, co robię), Lubię po prostu używać właściwości zdarzenia elementu, z którym pracuję.

Ma to tę zaletę, że można szybko i łatwo odłączyć zdarzenia.

var a = document.getElementById('someDivId'); 
a.onclick = function() {alert("Clicked!");}; 
// later... 
a.onclick = null; 

Należy jednak zachować ostrożność, ponieważ jeśli spróbujesz dodać drugą funkcję obsługi zdarzenia, zostanie ona zastąpiona pierwszą. Miej to na uwadze i wszystko powinno być w porządku.

+0

a.onclick = null nie działa, to dlatego, że funkcja bindEvent() działa w inny sposób, proszę, sprawdź oryginalne pytanie: Zamierzam edytować go i opublikować kod bindEvent() –

+0

dzięki pomysł z jlaceda znalazłem rozwiązanie, aby rozwiązać problem. –

-1

to z jQuery source:

jQuery.removeEvent = document.removeEventListener ? 
    function(elem, type, handle) { 
     if (elem.removeEventListener) { 
      elem.removeEventListener(type, handle, false); 
     } 
    } : 
    function(elem, type, handle) { 
     if (elem.detachEvent) { 
      elem.detachEvent("on" + type, handle); 
     } 
    }; 
+2

To tylko niewielka część systemu zdarzeń jQuery. Jak odpowie na to pytanie? –

+0

@jlaceda Sprawdzam rigth teraz pełny kod źródłowy. dzięki! –

+0

@amnotiam Uznałem, że jest to "najbardziej czysty metal" część procedury usuwania zdarzeń w jquery i będzie użyteczne odniesienie w tworzeniu niestandardowej funkcji unBind. Ale masz rację, że nie jest to pełna odpowiedź. Będę edytować w samodzielnej funkcji, która będzie oparta na tym fragmencie. – jlaceda

1

Nie jestem pewien, czy można rozpiąć anonimową funkcję dołączony poprzez javascript. Jeśli to możliwe, możesz łatwo usunąć element z DOM i ponownie go utworzyć. Spowoduje to pozbycie się wszelkich dołączonych programów obsługi zdarzeń.

+0

, ale JQuery może to zrobić! więc nie jest niemożliwe! –

+1

@JoshGuzman: jQuery wiąże dokładnie * jeden * handler na element i nigdy nie jest to przewodnik, który go przekazałeś. Twoje programy obsługi są przechowywane w 'jQuery.cache' Powiązuje ogólny program obsługi, który po wywołaniu, patrzy na obiekt zdarzenia, widzi, jaki typ zdarzenia jest, wyszukuje numer seryjny na elemencie, sprawdza, czy ten numer seryjny istnieje w 'jQuery.cache', a jeśli tak, sprawdza, czy podano jakiekolwiek procedury obsługi dla bieżącego typu zdarzenia, i wywołuje je/jeśli tak. –

+0

... ogólny program obsługi związany z jQuery jest również przywoływany w 'jQuery.cache', więc kiedy przychodzi czas na jego odwiązanie, wykonuje podobne wyszukiwanie i przekazuje go do natywnych metod, które rozpakowują programy obsługi. Oczywiście, kiedy robisz '.unbind ('click')', to po prostu czyści 'handlery' '' w 'jQuery.cache'. –

1

JavaScript nie zawiera listy detektorów zdarzeń dołączonych do węzła.

Można usunąć wszystkie detektory zdarzeń węzła ale stosując metodę Node.cloneNode, zobacz tutaj: https://developer.mozilla.org/En/DOM/Node.cloneNode

ten klonuje węzeł (oczywiście), ale nie klonować nasłuchiwania zdarzeń z nim związane.

Można też po prostu związać pustych funkcji jako detektorów zdarzeń:

function noop() {} 
bindEvent(myElement, "click", noop); 
+0

Ale funkcja, która jest powiązana z elementem jest anonimowa, co oznacza, że ​​nie mam odniesienia do nazwy, więc nie mogę ich przesłonić ani znać. –

+0

Ah tak, zapomniałem, że możesz mieć wiele detektorów zdarzeń dla tego samego zdarzenia. Nie możesz uzyskać odwołania do swojej anonimowej funkcji. Jeśli możesz zmienić swój kod, aby nie był anonimowy, byłoby to najlepsze rozwiązanie. W przeciwnym razie musisz po prostu zabić wszystkich słuchaczy zdarzeń i dodać te, które chcesz, z powrotem. – Griffin

+0

problem rozwiązany, dzięki jakikolwiek sposób. –

Powiązane problemy