2013-07-08 41 views
5

Các ý kiến ​​từ this question khiến tôi suy nghĩ về điều gì đó. Khi nào thì chính xác chức năng cháy $(document).ready()? Câu trả lời rõ ràng sẽ là "khi tài liệu đã sẵn sàng", nhưng chính xác thì khi nào?

Ví dụ: if I turned output buffering on and flushed my output while PHP continued executing, điều đó sẽ không gửi đầu ra tới trình duyệt không? Vì vậy, có cách nào tài liệu có thể sẵn sàng trước khi tập lệnh PHP đã hoàn thành thực thi hay không, sự kiện có chờ cho đến khi yêu cầu kết thúc không?


EDIT:

Các câu trả lời dường như về cơ bản đồng ý rằng sự kiện cháy khi khách hàng nghĩ rằng nó đã sẵn sàng.

Để có được một sự hiểu biết tốt hơn (mà tôi nên có lẽ thực hiện ở nơi đầu tiên), tôi chỉ cần thiết lập một thử nghiệm:

<?php ob_start(); ?> 
<html> 
<head> 
    <script type="text/javascript" src="lib/js/jquery-1.7.1.min.js"></script> 
    <script type="text/javascript"> 
     $(document).ready(function() { 
      alert("READY"); 
     }); 
    </script> 
</head> 
<body> 
<?php 
    ob_flush(); 
    for ($i=0; $i<999999; $i++) { 
     echo "HELLO$i\n"; 
     ob_flush(); 
    } 
?> 
</body> 
</html> 

Kết quả được rằng trong ví dụ này, các nội dung bắt đầu hiển thị trên ngay lập tức, nhưng cảnh báo đã không xảy ra cho đến khi vòng lặp hoàn thành hoặc tập lệnh hết thời gian chờ (30 giây).

Để điểm tùy thuộc vào trình duyệt bạn sử dụng, tôi đã cố gắng chèn này trong vòng lặp của tôi:

if ($i == 99) { 
    echo "</body></html>"; 
} 

Và Chrome dường như tự động sửa chữa nó bằng cách đặt những thẻ vào cuối trang (như đã thấy trong thanh tra web dev). Xem nguồn của trang cho thấy nó ở giữa, nơi tôi echo'ed nó mặc dù.

+1

ready() luôn sau khi php được thực hiện in trang html. nói cách khác, luôn luôn sau "" được gửi. – dandavis

+8

Sự kiện "sẵn sàng" là khái niệm bên trình duyệt. Trình duyệt xem xét trang "sẵn sàng" khi nó xử lý nội dung '' và chuẩn bị DOM, trong khi một số lần tìm nạp CSS và hình ảnh vẫn có thể đang chờ xử lý. Nó không biết hoặc quan tâm những gì máy chủ đang làm, trong bất kỳ ý nghĩa trực tiếp nào. – Pointy

+0

theo tài liệu nó được kích hoạt "ngay sau khi phân cấp DOM đã được xây dựng đầy đủ" nhưng trước khi mọi thứ đã thực sự được tải trên trang. Vì vậy, nếu bạn có hình ảnh, nó có thể được kích hoạt trước khi chúng được tải (đó là lý do tại sao jquery cũng cung cấp 'load' – scrappedcola

Trả lời

5

jQuery ready sự kiện cho các đám cháy tài liệu càng sớm càng jQuery xác định rằng DOM có thể truy cập. Cơ chế chính xác phụ thuộc vào trình duyệt.

Hãy xem source code có liên quan.

Thứ nhất, có một kiểm tra để xem liệu DOM có thể truy cập được tại thời điểm một nỗ lực đã được thực hiện để ràng buộc một người nghe đến sự kiện hay không. Nếu đúng như vậy, các cuộc gọi lại được lên lịch để kích hoạt ngay lập tức - mặc dù chúng không thực sự là đã kích hoạt ngay lập tức, để cho phép mã đã chiếm vị trí hiện tại để hủy các trình xử lý nếu cần.

Nếu DOM chưa truy cập được, nỗ lực được thực hiện để liên kết trình xử lý sự kiện với sự kiện DOMContentLoaded gốc của trình duyệt - đây là cách gốc "chính xác" để yêu cầu trình duyệt thông báo cho bạn khi DOM có sẵn, nhưng đó là một tính năng tương đối hiện đại. Nếu đây là không thể (điều này gần như chắc chắn cho thấy bạn đang chạy trong một phiên bản cũ của trình duyệt IE), mã rơi trở lại một vài cơ chế:

  • Hãy thử và gắn với sự kiện onreadystatechange của tài liệu. Đây không phải là bằng chứng ngu ngốc và sẽ muộn hơn DOMContentLoaded có thể đã được, nhưng nó khá tốt.
  • Quay lại sự kiện load của đối tượng window. Điều này thường sẽ muộn hơn nhiều so với DOM, nhưng đó là một sự cố không an toàn cuối cùng để đảm bảo sự kiện sẽ luôn luôn cháy cuối cùng.
  • Trường hợp xấu nhất: tiếp tục bỏ phiếu cho DOM cho đến khi có thể truy cập được.

Từ góc độ PHP, nó là thể (nhưng không chắc) cho điều này xảy ra trước khi kịch bản PHP của bạn đã hoàn tất thi công. Có các tình huống (chẳng hạn như bỏ phiếu dài), nơi sự kiện sẽ kích hoạt trước khi tập lệnh của bạn hoàn tất, nhưng điều này sẽ chỉ xảy ra trong các trình duyệt cũ hơn. Tuy nhiên, trong những trường hợp này, bạn sẽ không (không nên) sử dụng những sự kiện này, bạn chỉ cần đặt các phần tử <script> thích hợp vào phần thân của trang để cho phép chúng được thực thi ngay khi chúng được tải, mà không đang đợi phần còn lại của DOM.

Cá nhân, tôi không bao giờ sử dụng bất kỳ sự kiện tải trọng nào, nhiều hơn hoặc ít hơn cho lý do đó. YMMV.

0

Nó bắn sau khi hệ thống phân cấp DOM đã được xây dựng hoàn chỉnh và không có nhiều mã PHP để thực hiện (như PHP mã được thực thi trước khi trang được gửi).

Điều này có nghĩa là nó được thực thi ngay khi khách hàng nhận được trang. Những thứ khác có thể tải sau đó, chẳng hạn như hình ảnh, CSS và Javascript khác.

0

Document.ready() được kích hoạt khi tải DOM hoàn tất. Khi tất cả HTML hiện diện, sự kiện DOM ready sẽ kích hoạt.

PHP sẽ không can thiệp với DOM ready vì PHP là ngôn ngữ mã hóa phía máy chủ. Nó sẽ được xử lý từ máy chủ, máy chủ sẽ gửi trang được yêu cầu, sau đó broswer của bạn tải trang và các sự kiện DOM ready cháy.

Sự khác biệt giữa DOM ready và cửa sổ load là tải sẽ đợi cho đến khi mỗi ảnh/css được tải. Thẻ có trong HTML nhưng hình ảnh không được hiển thị.

Về cơ bản, chúng ta có thể nói rằng DOM sẵn sàng bị sa thải khi trình duyệt đọc thẻ HTML bế mạc (</html>)

3

Ví dụ, nếu tôi bật bộ đệm đầu ra và xả đầu ra của tôi trong khi PHP tiếp tục thực hiện, điều đó sẽ không gửi đầu ra tới trình duyệt không?

Có, nó sẽ gửi đầu ra, nhưng điều đó không có nghĩa là trình duyệt cho rằng máy chủ đã hoàn tất. Tôi biết nó không phải là PHP, nhưng tôi thích bài viết của Perl Suffering from Buffering. Tài liệu đã sẵn sàng khi UserAgent cho rằng nó đã sẵn sàng. Tuy nhiên, trình duyệt sẽ giữ cho socket mở, trong khi nó vẫn cho rằng nó đang nhận dữ liệu và không có tín hiệu END nào được gửi đi.

Vì vậy, có cách nào tài liệu có thể sẵn sàng trước khi tập lệnh PHP đã hoàn thành việc thực thi hay sự kiện chờ cho đến khi yêu cầu kết thúc?

Thông thường trình duyệt sẽ đợi cho đến khi máy chủ kết thúc gửi dữ liệu. Nếu bạn đang xả đầu ra, có thể máy chủ web có thể hết thời gian chờ trong khi tập lệnh vẫn đang chạy, ví dụ, tôi nghĩ Apache có mặc định là 2 phút. Nếu máy chủ gửi tín hiệu kết thúc, tài liệu của bạn đã hoàn tất và trình duyệt của bạn có thể chuẩn bị DOM và kích hoạt sự kiện DOMReady, ngay cả khi tập lệnh của bạn vẫn đang chạy trên máy chủ.


Trái với một số ý kiến ​​khác </body></html> không chỉ tốt về DOM là sẵn sàng, chủ yếu là do một trang chưa bị thay đổi (có lỗi chính tả hoặc không bao gồm những thẻ kết thúc). Trong những trường hợp đó, trình duyệt sẽ vẫn hiển thị trong Quirksmode và kích hoạt DOMReady.

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