2009-04-15 10 views
72

Tôi đang cố gắng phát hiện khi khung nội tuyến và nội dung của iframe đã tải nhưng không có nhiều may mắn. Ứng dụng của tôi lấy một số đầu vào trong trường văn bản trong cửa sổ chính và cập nhật iframe để cung cấp 'xem trước trực tiếp'Phát hiện khi nội dung Khung nội tuyến đã tải (Trình duyệt chéo)

Tôi bắt đầu với mã sau (YUI) để phát hiện khi sự kiện tải iframe xảy ra.

$E.on('preview-pane', 'load', function(){ 
    previewBody = $('preview-pane').contentWindow.document.getElementsByTagName('body')[0]; 
} 

'ô xem trước' là ID của khung nội tuyến của tôi và tôi đang sử dụng YUI để đính kèm trình xử lý sự kiện. Tuy nhiên, cố gắng truy cập nội dung trong hàm gọi lại của tôi (khi tải iframe) không thành công, tôi nghĩ vì iframe tải trước khi trình xử lý sự kiện sẵn sàng. Mã này hoạt động nếu tôi trì hoãn việc tải khung nội tuyến bằng cách tạo tập lệnh php tạo ra tập lệnh ngủ.

Về cơ bản, tôi hỏi phương pháp tiếp cận chính xác trên các trình duyệt để phát hiện thời điểm iframe đã tải và tài liệu của nó đã sẵn sàng là gì?

+1

Bắt đầu với YUI là một ý tưởng tồi (cũng như bất kỳ thư viện JS khác). Tại sao? Bởi vì bạn không thể biết được thư viện đó đang làm gì. Nếu họ không thể hỗ trợ "tải" đầy đủ, bạn nên làm điều đó cho mình trong javascript rõ ràng và dễ đọc. – Christian

+2

Bạn thường có thể đọc mã nguồn của thư viện @Christian. Tôi tìm thấy điều này thường cung cấp cho bạn những lời khuyên tuyệt vời về cách tự mình làm bất kể bạn có sử dụng triển khai của họ hay không. – AJP

+0

@AJP Bạn hiểu nhầm quan điểm của tôi. Nếu bạn đang làm một cái gì đó bạn không chắc chắn, tốt hơn là có ít mã hơn nên có ít chỗ cho lỗi hơn. – Christian

Trả lời

58

để phát hiện khi các iframe đã nạp và tài liệu của mình bạn đã sẵn sàng?

Thật lý tưởng nếu bạn có thể đặt khung nội tuyến tự cho mình biết từ tập lệnh bên trong khung. Ví dụ, nó có thể gọi một hàm cha trực tiếp để nói nó đã sẵn sàng. Việc chăm sóc luôn được yêu cầu với việc thực thi mã chéo vì mọi thứ có thể xảy ra theo thứ tự bạn không mong đợi. Một lựa chọn khác là đặt ‘var isready = true;’ trong phạm vi riêng của nó và có đoạn mã phụ huynh sniff cho ‘contentWindow.isready’ (và thêm trình xử lý tải lên nếu không).

Nếu vì một lý do nào đó không thực tế để có tài liệu iframe hợp tác, bạn đã có vấn đề tải cuộc đua truyền thống, cụ thể là ngay cả khi yếu tố này là ngay bên cạnh nhau:

<img id="x" ... /> 
<script type="text/javascript"> 
    document.getElementById('x').onload= function() { 
     ... 
    }; 
</script> 

không đảm bảo rằng mục sẽ không được tải trước khi tập lệnh thực thi.

Những cách ra khỏi tải chủng tộc là:

  1. trên IE, bạn có thể sử dụng tài sản ‘readyState’ để xem nếu điều gì đó đã được nạp;

  2. nếu có mục chỉ có sẵn với JavaScript được chấp nhận, bạn có thể tạo mục động, đặt chức năng sự kiện ‘onload’ trước khi đặt nguồn và thêm vào trang. Trong trường hợp này, nó không thể được tải trước khi gọi lại được thiết lập;

  3. theo cách cũ-trường bao gồm nó trong đánh dấu:

    <img onload="callback(this)" ... />

Inline 'onsomething' xử lý trong HTML là hầu như luôn luôn là điều sai lầm và để tránh được, nhưng trong này trường hợp đôi khi đó là tùy chọn ít xấu nhất.

+0

Cảm ơn. Giải pháp của tôi kiểm tra readyState (nếu tồn tại), sau đó các phần tử body innerHTML length để xem nó đã được tải chưa. Nếu không, hãy gắn trình xử lý sự kiện tải. Dường như làm việc ok –

+7

-1 - sự kiện nội tuyến không phải là "xấu", đó chỉ là mốt nhất thời hiện tại. Trong thực tế, các sự kiện nội tuyến dễ dàng hơn để gỡ lỗi và hiểu, không giống như các đối tác ma thuật của chúng (trong đó, mặt khác, dễ đính kèm, ngăn xếp và sử dụng liền mạch hơn). – Christian

+0

@Christian, sự kiện nội tuyến cũng là tùy chọn tốt nhất khi bạn cần đính kèm sự kiện vào mọi phần tử trong danh sách rất dài. Vì bạn đã tạo vòng lặp để xây dựng danh sách ở phía máy chủ, nên việc đính kèm sự kiện nội tuyến cũng hiệu quả hơn nhiều. – haknick

43

Xem this bài đăng blog. Nó sử dụng jQuery, nhưng nó sẽ giúp bạn ngay cả khi bạn không sử dụng nó.

Về cơ bản bạn thêm video này vào document.ready()

$('iframe').load(function() { 
    RunAfterIFrameLoaded(); 
}); 
+0

Thú vị, nhưng vấn đề tôi có là với các sự kiện tải và thời gian. Tôi đang lắng nghe sự kiện tải trọng theo lời khuyên của bài viết đó. –

+0

tôi đã thử điều này với 'console.log'. nó được ghi lại sau khi khung nội tuyến đã được tải. – shorif2000

1

Đối với những người sử dụng React, phát hiện sự kiện tải khung nội tuyến gốc cũng đơn giản như cài đặt onLoad trình xử lý sự kiện trên phần tử khung nội tuyến.

<iframe src={'path-to-iframe-source'} onLoad={this.loadListener} frameBorder={0} />

1

Đối với bất cứ ai sử dụng Ember, điều này sẽ làm việc như mong đợi:

<iframe onLoad={{action 'actionName'}} frameborder='0' src={{iframeSrc}} />