7

Tôi hiện đang phát triển Bài kiểm tra Đơn vị cho một phương pháp Javascript để phát hiện sự sẵn sàng của tài liệu. Mã này đã ở cấp khung, vì vậy hãy tránh đề cập đến việc này đang được triển khai trong jQuery hoặc một thư viện khác.Làm thế nào để kích hoạt sự kiện "onload" trên tài liệu trong IE

tôi đã mô phỏng thành công sự kiện 'readystatechange' thay đổi với đoạn mã sau:

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

Tôi thất bại trong việc làm tương tự cho sự kiện 'tải'. Đoạn mã sau dẫn đến lỗi đối số không hợp lệ trong IE7, được gọi bằng cách gọi đến fireEvent trên dòng cuối cùng:

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

Có ai đã làm điều này, hoặc không làm điều này trước đây? Tôi cũng quan tâm đến bất kỳ đề xuất nào để kích hoạt sự kiện theo một cách khác.

Edit: sau đề nghị bởi Crescent Fresh, tôi đã thay đổi mã của tôi để:

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

Không có lỗi hơn, nhưng người nghe cho 'onload' không cháy. Đây là cách tôi định cấu hình nó:

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

Sự kiện 'tải' thực sự kích hoạt trên' document.body'. Vì vậy, bạn có thể thử thay vì 'document.body.fireEvent ('onload', event)'. Tôi nghi ngờ rằng sẽ thực sự cháy xử lý gắn liền với 'onload' mặc dù. Nếu tôi đã bị sốc ... –

+0

Bạn là 100% đúng. Kích hoạt sự kiện trên document.body có thể được thực hiện mà không có lỗi, nhưng các trình nghe kèm theo document.attachEvent không được kích hoạt. –

+0

@Eric: suy nghĩ nhiều. Đó là một người đàn ông bummer. –

Trả lời

4

Theo this page at MSDN, không có sự kiện onload cho document.

Bạn muốn hoặc là window.onload hoặc document.body.onload. Chúng giống hệt nhau trong IE: vì lý do lịch sử, <body onload="..."> thực sự đặt window.onload, do đó, MS đã quyết định đặt document.body.onload bí danh là window.onload.

Vấn đề với điều này là - như Eric đã đề cập trong các nhận xét - rằng dường như không có cách nào để tự cháy các sự kiện cửa sổ, có nghĩa là có thể không có giải pháp cho vấn đề của Eric.

+1

@Christoph: điểm tốt, đã được đề cập bởi Crescent Fresh: Tôi nên kích hoạt sự kiện trên document.body thay thế. Nhận xét thú vị về window.onload nhưng không hữu ích vì cửa sổ không có phương thức fireEvent. –

+0

@Christoph cảm ơn bạn đã chỉnh sửa câu trả lời của mình. Tôi sẽ chấp nhận nó như một kết luận cho cuộc thảo luận thú vị này. –

0

Sự kiện tải sẽ kích hoạt khi tài liệu (bao gồm tài nguyên bên ngoài như hình ảnh) đã được tải đầy đủ và không trước đó.

Bạn nhận được kết quả gì từ những nỗ lực của bạn để bắn readystatechange? Giá trị readyState có thực sự thay đổi không? Có hay không, đó không phải là sử dụng nhiều: hoặc là bạn kích hoạt sự kiện với readyState mà không thay đổi hoặc bạn làm như vậy với readyState không phản ánh đúng trạng thái của tài liệu.

+0

@NickFitz Cảm ơn câu trả lời. Tôi không cố gắng để thay đổi giá trị của document.readyState, mà vẫn còn 'hoàn thành' trước (vì tôi có một chờ đợi cho đến khi readyState trở thành 'hoàn thành') và sau khi thử nghiệm của tôi. Hãy nhớ rằng mã này được viết cho các bài kiểm tra đơn vị. –

+0

@NickFitz: Eric chỉ đang cố gắng mô phỏng sự kiện 'tải' trong thế giới thực cho các bài kiểm tra đơn vị địa phương. –

+0

Nếu đó là một bài kiểm tra đơn vị thì bạn không cần phải kích hoạt bất kỳ sự kiện nào. Đơn giản chỉ cần tạo một đối tượng sự kiện giả định với các giá trị đã biết và gọi trực tiếp trình xử lý sự kiện, sau đó kiểm tra xem nó đã tạo ra kết quả chính xác cho các giá trị đó chưa. Nếu không, đây không phải là kiểm tra đơn vị, đó là kiểm thử tích hợp: bạn đang thử nghiệm cách mã tích hợp với các cơ chế xử lý sự kiện nội bộ của trình duyệt. – NickFitz

3

Vì một lý do nào đó, có vẻ như IE ghi đè thuộc tính onload của window bằng một đối tượng trống sau khi DOM được tải. Ít nhất đó là trường hợp khi bạn cố gắng truy cập nó từ bên trong bất kỳ trình xử lý sự kiện nào của một phần tử 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> 

Trong trường hợp này, bạn sẽ thấy cửa sổ đó được nhận ra là hàm ban đầu, thì bạn sẽ thấy cảnh báo "Kiểm tra". Khi bạn nhấp vào tiêu đề, bạn sẽ thấy cửa sổ đó. Bây giờ, tải xuống là object. Tôi đã cố gắng lặp qua các thuộc tính của đối tượng, nhưng nó trống. Nó không tuyệt.

Một cách giải quyết khác là lấy chức năng trong phạm vi có thể truy cập và gán nó vào một thuộc tính khác mà bạn có thể kích hoạt một cách thuận tiện ...

<!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> 

Tôi không thể nghĩ ra bất kỳ cách nào khác để giải quyết vấn đề này ngay bây giờ.

+0

@Josh Stodola thú vị ... Tôi phát hiện ngày hôm nay rằng document.attachEvent không phải là một chức năng trong IE: bạn có thể gọi nó là tất nhiên, nhưng (typeof document.attachEvent) trả về "đối tượng" và cả document.attachEvent.call và tài liệu. attachEvent.apply không được xác định ... trình duyệt này sẽ không bao giờ ngừng làm tôi ngạc nhiên. –