2012-02-26 41 views
28

Tôi đang cố gắng giúp phát triển thư viện và tôi đang cố gắng làm việc với tải trang.
Trong quá trình tôi muốn làm cho thư viện hoàn toàn tương thích với việc sử dụng trì hoãn và không đồng bộ.Cách phát hiện xem DOMContentLoaded đã được kích hoạt chưa

Điều tôi muốn đơn giản:
Làm cách nào để biết rằng DOMContentLoaded đã được kích hoạt khi tệp được thực thi?

Tại sao điều này lại khó khăn như vậy?
Trong IE, document.readyState hiển thị tương tác trước DOMContentLoaded.
I sẽ không sử dụng tính năng phát hiện trình duyệt theo bất kỳ cách nào, điều này trái ngược với chính sách của tôi và những người tham gia còn lại.

Giải pháp thay thế chính xác là gì?

Chỉnh sửa:

Dường như tôi chưa đủ rõ ràng. Tôi là không phải muốn biết sự kiện tải đã xảy ra chưa !!! Tôi đã biết cách giải quyết vấn đề đó! Tôi muốn biết cách giải quyết với DOMContentLoaded !!!

+0

Đặt người nghe đặt thuộc tính hoặc biến. Nếu được đặt, sự kiện đã được gửi đi. Tất nhiên bạn có thể đang ở trong một trình duyệt không hỗ trợ sự kiện, trong trường hợp đó nó sẽ không bao giờ xảy ra. – RobG

+0

@RobG Tôi đã có câu trả lời cho các trình duyệt mà ado không hỗ trợ DOMContentLoaded. Đối với những người, tôi sử dụng sự kiện tải và sự kiện onload. Tôi vẫn không có câu trả lời cho câu hỏi tôi đã thực hiện – brunoais

+0

Không có sự kiện "onload", có thuộc tính * onload */thuộc tính để thiết lập người nghe cho sự kiện * load *. Nếu bạn muốn biết rõ ràng nếu DOMContentLoaded đã xảy ra, hãy thiết lập một người nghe và xem nó có được gọi hay không. – RobG

Trả lời

29

tôi sẽ nghĩ rằng bạn có thể sử dụng:

if (document.readyState === "complete" || document.readyState === "loaded") { 
    // document is already ready to go 
} 

này đã được hỗ trợ trong IE và webkit trong một thời gian dài. Nó đã được thêm vào Firefox trong 3.6. Đây là số spec. "loaded" dành cho các trình duyệt Safari cũ hơn.

Nếu bạn muốn biết khi trang đã được phân tích cú pháp, nhưng tất cả subresources chưa được kích hoạt, bạn có thể thêm "tương tác" giá trị:

if (document.readyState === "complete" 
    || document.readyState === "loaded" 
    || document.readyState === "interactive") { 
    // document has at least been parsed 
} 

Hơn thế nữa, nếu bạn thực sự chỉ muốn biết khi DOMContentLoaded đã kích hoạt, thì bạn sẽ phải cài đặt một trình xử lý sự kiện cho điều đó (trước khi nó kích hoạt) và thiết lập một cờ khi nó kích hoạt.

This MDN documentation cũng là một đọc thực sự tốt về hiểu thêm về trạng thái DOM.

+0

Bạn không trả lời câu hỏi. Tôi muốn biết về sự kiện DOMContentLoaded, không tải sự kiện. Sự kiện tải dễ dàng, DOMContentLoaded tôi không biết. – brunoais

+1

@brunoais - sau đó cài đặt trình xử lý cho sự kiện DOMContentLoaded và đặt cờ khi nó kích hoạt. Tôi không nghĩ có một lựa chọn khác. – jfriend00

+1

Nếu bạn muốn bao gồm khi tài liệu đã được phân tích cú pháp, nhưng các tài nguyên phụ vẫn đang tải, bạn cũng có thể kiểm tra "tương tác". Xem ví dụ thứ hai tôi đã thêm vào câu trả lời của mình. – jfriend00

1

Hãy thử điều này hoặc nhìn vào link

<script> 
    function addListener(obj, eventName, listener) { //function to add event 
     if (obj.addEventListener) { 
      obj.addEventListener(eventName, listener, false); 
     } else { 
      obj.attachEvent("on" + eventName, listener); 
     } 
    } 

    addListener(document, "DOMContentLoaded", finishedDCL); //add event DOMContentLoaded 

    function finishedDCL() { 
     alert("Now DOMContentLoaded is complete!"); 
    } 
</script> 

Chú giải này

Nếu bạn có một <script> sau một <link rel="stylesheet" ...>

trang sẽ không hoàn thành phân tích cú pháp - và DOMContentLoaded sẽ không cháy - cho đến khi biểu định kiểu được tải

+1

Thử tốt nhưng điều đó không đi sau những gì tôi thực sự sau. Điều đó không kiểm tra xem sự kiện đã bị sa thải hay chưa, điều đó chỉ kiểm tra xem sự kiện có bị sa thải hay không. Tôi biết cách kiểm tra xem sự kiện này có bị sa thải hay không nhưng tôi không biết cách kiểm tra xem sự kiện đã bị sa thải hay chưa – brunoais

0

Nếu bạn muốn biết "chính xác" nếu DOMContentLoaded đã bị sa thải, bạn có thể sử dụng một lá cờ boolean như thế này:

var loaded=false; 
document.addEventListener('DOMContentLoaded',function(){ 
loaded=true; 
... 
} 

sau đó kiểm tra với:

if(loaded) ... 
+0

Nice try :). Đó thực sự không phải là câu trả lời. Khi tôi muốn nó hoạt động chính xác với tất cả các trình duyệt (chính) và với async và trì hoãn, tôi không thể chắc chắn rằng nó sẽ hoạt động như mong đợi do IE. – brunoais

+0

IE không phải là trình duyệt: D – deviato

+0

Chúng tôi muốn <_ <... – brunoais

8

Các document.readyState được thay đổi khi sự kiện này là bắn . Vì vậy, bạn có thể kiểm tra giá trị readyState và cách này cho biết sự kiện có được kích hoạt hay không. Dưới đây là một mã để chạy start() khi tài liệu đã sẵn sàng cho nó:

if (/comp|inter|loaded/.test(document.readyState)){ 
    // In case DOMContentLoaded was already fired, the document readyState will be one of "complete" or "interactive" or (nonstandard) "loaded". 
    // The regexp above looks for all three states. A more readable regexp would be /complete|interactive|loaded/ 
    start(); 
}else{ 
    // In case DOMContentLoaded was not yet fired, use it to run the "start" function when document is read for it. 
    document.addEventListener('DOMContentLoaded', start, false); 
} 
+0

giải thích cách thức hoạt động của – brunoais

+0

@brunoais NP, tôi đã thêm giải thích làm nhận xét, bây giờ có rõ ràng hơn không? – oriadam

+0

Vậy ... về cơ bản bạn đã chọn câu trả lời của friend00 và xây dựng câu trả lời với dữ liệu từ câu trả lời của mình? – brunoais

-3

Đây là điều, nếu một số thư viện khác (chẳng hạn như jQuery) đã sử dụng DOMContentLoaded, bạn không thể sử dụng nó một lần nữa. Đó có thể là tin xấu, bởi vì bạn kết thúc mà không thể sử dụng nó. Bạn sẽ nói, tại sao không chỉ sử dụng $(document).ready(), bởi vì, NO !, không phải mọi thứ đều cần sử dụng jQuery, đặc biệt nếu nó là một thư viện khác.

+1

Không đúng khi bạn không thể có nhiều người nghe sự kiện. Vui lòng đọc trên https://developer.mozilla.org/en-US/docs/DOM/document.addEventListener và mẫu Xuất bản/Đăng ký (pub sub): https://msdn.microsoft.com/en-us/ thư viện/ff649664.aspx – dotnetCarpenter

Các vấn đề liên quan