2009-12-09 11 views
7

Aktualnie rozwijam testy jednostek dla metody JavaScript, która wykrywa gotowość dokumentu. Ten kod jest już na poziomie struktury, więc proszę unikać wzmianek o tym, że jest już zaimplementowany w jQuery lub innej bibliotece.Jak rozpalić zdarzenie "onload" na dokumencie w IE

ja z powodzeniem symulowane zdarzenia „readystatechange” zmiana z następującego kodu:

var event; 
event = document.createEventObject(); 
event.type = 'readystatechange'; 
document.fireEvent('onreadystatechange',event); 

nie udało mi się zrobić to samo dla zdarzenia „obciążenie”. Poniższe wyniki kod błędu w argumencie nieważny w IE7, rzucony przez wywołanie fireEvent w ostatnim wierszu:

event = document.createEventObject(); 
event.type = 'load'; 
document.fireEvent('onload',event); 

Każdy użytkownik zrobił to, czy udało się to zrobić wcześniej? Interesuje mnie też każda sugestia, by wystrzelić to wydarzenie w inny sposób.

Edit: zgodnie z sugestią przez Crescent Fresh, zmieniłem mojego kodu:

event = document.createEventObject(); 
event.type = 'load'; 
document.body.fireEvent('onload',event); 

nie ma więcej błędów, ale słuchacz dla 'onload' nie uruchamia. Oto jak ja skonfigurowany go:

document.attachEvent('onload',listener); 
+1

Zdarzenie 'load' faktycznie uruchamia się na' document.body'. Możesz więc spróbować zamiast tego 'document.body.fireEvent ('onload', event)'. Wątpię jednak, by faktycznie uruchamiał uchwyty dołączone do 'onload'. Gdyby tak było, byłbym zszokowany ... –

+0

Masz 100% racji. Wypalanie zdarzenia na document.body może odbywać się bezbłędnie, ale detektory powiązane z document.attachEvent nie są wyzwalane. –

+0

@Eric: myślałem tak bardzo. To człowiek, który nie ma racji. –

Odpowiedz

4

Według this page at MSDN, dla nie ma zdarzenia dla .

Chcesz albo window.onload lub document.body.onload. Są one identyczne w IE: z powodów historycznych, <body onload="..."> faktycznie ustawia window.onload, więc MS postanowiło uczynić document.body.onload pseudonimem window.onload.

Problem polega na tym, że - jak wspomniał Eric w komentarzach - nie istnieje sposób ręcznego wywoływania zdarzeń w oknie, co oznacza, że ​​może nie być rozwiązania problemu Erica.

+1

@ Christoph: dobry punkt, o którym już wspominał Crescent Fresh: Zamiast tego powinienem wydać to wydarzenie na document.body. Ciekawy komentarz do window.onload, ale nie tak pomocny, ponieważ okno nie ma metody fireEvent. –

+0

@ Christoflo podziękowania za edycję odpowiedzi. Przyjmę to jako zakończenie tej interesującej dyskusji. –

0

Impreza obciążenie będzie ogień, gdy dokument (w tym środków zewnętrznych, takich jak obrazy) jest w pełni załadowany, a nie wcześniej.

Jakich rezultatów uzyskuje się, próbując odpalić readystatechange? Czy wartość readyState rzeczywiście się zmienia? Niezależnie od tego, czy nie jest to zbyt użyteczne: albo wywołujesz zdarzenie z readyState, które się nie zmieniło, albo robisz to z readyState, które nie jest poprawnym odzwierciedleniem stanu dokumentu.

+0

@NickFitz Dziękuję za odpowiedź. Nie próbuję zmienić wartości dokumentu.readyState, który pozostaje "kompletny" przed (ponieważ mam czekać, aż readyState stanie się "kompletny") i po moim teście. Należy pamiętać, że ten kod jest napisany dla testów jednostkowych. –

+0

@NickFitz: Eric próbuje symulować rzeczywiste zdarzenie 'load' dla lokalnych testów jednostkowych. –

+0

Jeśli jest to test jednostkowy, nie powinieneś w ogóle wywoływać żadnych zdarzeń. Po prostu stwórz fałszywy obiekt zdarzeń o znanych wartościach i wywołaj bezpośrednio procedurę obsługi zdarzeń, a następnie sprawdź, czy wygenerował poprawne wyniki dla tych wartości. W przeciwnym razie nie jest to test jednostkowy, jest to test integracyjny: testujesz, jak kod integruje się z wewnętrznymi mechanizmami obsługi zdarzeń przeglądarki. – NickFitz

3

Z jakiegoś powodu wygląda na to, że IE przesłania właściwość z pustym obiektem po wczytaniu DOM. Przynajmniej tak jest w przypadku, gdy próbują uzyskać do niego dostęp z poziomu dowolnej obsługi zdarzeń elementu DOM ...

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Test by Josh</title> 
    <script type="text/javascript"> 
     window.onload = function() { 
     alert("Test"); 
     } 
     alert(typeof window.onload); 
    </script> 
    </head> 
    <body> 
    <h1 onclick="alert(typeof window.onload);">Test</h1> 
    </body> 
</html> 

W tej sytuacji, zobaczysz, że window.onload jest rozpoznawana jako funkcję początkowo, wtedy zobaczysz alert "Testuj". Po kliknięciu nagłówka zobaczysz, że window.onload jest teraz object. Próbowałem iterować po właściwościach obiektu, ale jest on pusty. To nie jest fajne.

Jednym z lirów jest obejście tej funkcji w dostępnym zakresie i przypisanie jej do innej właściwości, którą można wystrzelić w dogodnym dla siebie momencie ...

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Test by Josh</title> 
    <script type="text/javascript"> 
     window.onload = function() { 
     alert("Test"); 
     }   
    </script> 
    </head> 
    <body> 
    <h1 onclick="window.onloadfix()">Test</h1> 
    <!-- Could potentially be injected via server-side include if needed --> 
    <script type="text/javascript"> 
     window.onloadfix = function() { 
     window.onload(); 
     } 
    </script> 
    </body> 
</html> 

Nie mogę wymyślić innego sposobu rozwiązania tego problemu w tej chwili.

+0

@Josh Stodola interesujące ... Odkryłem dzisiaj, że document.attachEvent nie jest funkcją w IE: można go nazwać oczywiście, ale (typeof document.attachEvent) zwraca "obiekt" i dokument.attachEvent.call i dokument. attachEvent.apply są niezdefiniowane ... ta przeglądarka nigdy nie przestanie mnie zaskakiwać. –

Powiązane problemy