2011-08-27 13 views
15

dostaję Uncaught TypeError: Illegal invocation dla obu wersji tego próbując umieścić w dół EventListener: (pojawia się błąd, gdy słuchacz powinien być dodany, a nie po kliknięciu na tarczy)Uncaught TypeError: Nielegalna wezwanie na addEventListener

ronan.addEventListener("click", alert, false);

addEventListener.apply(ronan, ["click", alert, false]);

ronan jest div elementem, który jest zwracany z powodzeniem przez konsolę więc nie sądzę, że jest problem. Jakieś pomysły, dlaczego dostaję ten błąd? Przeczytałem wątek this i nie mogłem tego zrozumieć.

+0

Może powinienem był poczekać do rana, aby przesłać to –

+1

To może być "alert" ... natywna funkcja. Czy na jego miejscu działa pusta funkcja() {}? – James

+0

@ J-P nie, to nie pomogło –

Odpowiedz

29

Musisz zawinąć alert w jedną funkcję. To zadziała:

ronan.addEventListener("click", function() { alert('Hi'); }, false); 

Oto dowód na fiddle. Samo używanie nie działa, ponieważ podczas wykonywania detektora wartość this w obrębie tej funkcji jest ustawiona na obiekt, na którym nasłuchuje. Na przykład, jeśli ustawisz detektor na ronan, w tym słuchaczu this === ronan. Stanowi to problem dla alert, ponieważ ta funkcja oczekuje, że this będzie równa window. Można to obejść (gra słów nie przeznaczonych) owijając funkcję w innej funkcji lub poprzez wiązanie go do tego, co oczekuje this być:

document.body.addEventListener('click', alert.bind(window), false); 

Nie zapominaj, że w IE < 9 trzeba użyć attachEvent zamiast addEventListener.


Uwaga na użyciu apply/call z addEventListener

swojej drugiej próbie nie zadziała, ponieważ próbujesz zastosować argumenty window.addEventListener, w przeciwieństwie do HTMLElement.prototype.addEventListener, który jest różny funkcja całkowicie:

// This won't work 
addEventListener.apply(ronan, ["click", alert.bind(window), false]); 

// This will work 
HTMLElement.prototype.addEventListener.apply(ronan, ['click', alert.bind(window), false]); 
+1

Och, słowo, masz rację. W rzeczywistości nie używam nawet prototypowego obiektu, tylko podstawy, ale twoja metoda wciąż działała bez części prototypowej. Prawdopodobnie powinienem był wiedzieć o bind(), ponieważ mój JS jest tak skoncentrowany na DOM. Wielkie dzięki za poświęcony czas! –

Powiązane problemy