2011-04-26 37 views
41

Có ai biết nếu có một thứ như vậy không?jQuery iframe load() sự kiện?

Tôi có một iframe đó là được chèn với $.ajax() và tôi muốn làm một số nội dung sau khi các nội dung từ các iframe là hoàn toàn tải:

.... 
success: function(html){ // <-- html is the IFRAME (#theiframe) 
      $(this).html(html); // $(this) is the container element 
      $(this).show(); 
      $('#theiframe').load(function(){ 
      alert('loaded!'); 
      } 
.... 

nó hoạt động, nhưng tôi thấy IFRAME được nạp hai lần (các cảnh báo cũng hiển thị hai lần).

+0

Hãy thử thiết lập src của khung nội tuyến trước khi thêm nó vào DOM. Điều này sẽ ngăn sự kiện tải kích hoạt hai lần. – Abe

Trả lời

47

Nếu có thể, bạn nên xử lý sự kiện load trong tài liệu iframe và gọi ra một hàm trong tài liệu có chứa. Điều này có lợi thế là làm việc trong tất cả các trình duyệt và chỉ chạy một lần.

Trong tài liệu chính:

function iframeLoaded() { 
    alert("Iframe loaded!"); 
} 

Trong tài liệu iframe:

window.onload = function() { 
    parent.iframeLoaded(); 
} 
+0

hey this works! nhưng làm thế nào tôi có thể gọi một hàm bên trong hàm 'jQuery (document) .ready' của tài liệu gốc? – Alex

+0

@Alex: Bạn cần đảm bảo hàm toàn cục, bạn có thể thực hiện bằng cách khai báo nó như là một biến trong phạm vi toàn cục trước khi gán giá trị cho biến bên trong hàm 'ready()' của bạn, hoặc bằng explictly gán nó như là một thuộc tính của 'window' bên trong hàm' ready() 'của bạn. Ví dụ: '$ (document) .ready (function() {window.iframeLoaded = function() {alert (" Load ");};/* Các công cụ khác ở đây * /})'; –

+0

có vẻ như vấn đề tải đôi của tôi là tôi gói iframe giữa các thẻ DIV. Đối với một số lý do khiến trình duyệt tải lại iframe nếu bạn làm điều này ... – Alex

2

Bạn có thể sử dụng phương thức Contents của jquery để lấy nội dung của khung nội tuyến.

3

Đó là hành vi tương tự như tôi đã thấy: iframe load() sẽ kích hoạt trước trên iframe trống, sau đó là lần thứ hai khi trang của bạn được tải.

Chỉnh sửa: Hmm, thú vị. Bạn có thể tăng bộ đếm trong trình xử lý sự kiện của mình và a) bỏ qua sự kiện load đầu tiên hoặc b) bỏ qua mọi sự kiện load trùng lặp.

+0

nếu tôi thêm 'alert ($ (this) .attr ('src'));' bên trong hàm load, tôi nhận được cùng một giá trị hai lần ... – Alex

2

Nếu bạn muốn nó được chung chung hơn và độc lập, bạn có thể sử dụng cookie. Nội dung khung nội tuyến có thể đặt cookie. Với jquery.cookie và một bộ đếm thời gian (hoặc trong trường hợp này là bộ đếm thời gian javascript), bạn có thể kiểm tra xem cookie có được đặt mỗi giây hay không.

//token should be a unique random value which is also sent to ifame to get set 
iframeLoadCheckTimer = window.setInterval(function() { 
     cookieValue = $.cookie('iframeToken'); 
     if (cookieValue == token) 
     { 
      window.clearInterval(iframeLoadCheckTimer); 
      $.cookie('iframeToken', null, { 
       expires: 1, 
       path: '/' 
     }); 
     } 
}, 1000); 
6

Dọc theo dòng Tim Down's answer nhưng tận dụng jQuery (được đề cập bởi OP) và lỏng lẻo khớp nối trang chứa và các iframe, bạn có thể làm như sau:

Trong iframe:

<script> 
    $(function() { 
     var w = window; 
     if (w.frameElement != null 
       && w.frameElement.nodeName === "IFRAME" 
       && w.parent.jQuery) { 
      w.parent.jQuery(w.parent.document).trigger('iframeready'); 
     } 
    }); 
</script> 

Trong trang có chứa:

<script> 
    function myHandler() { 
     alert('iframe (almost) loaded'); 
    } 
    $(document).on('iframeready', myHandler); 
</script> 

Ifra tôi kích hoạt một sự kiện trên tài liệu của cửa sổ cha mẹ (có khả năng tồn tại) - hãy cẩn thận rằng tài liệu gốc cần một cá thể jQuery của chính nó để làm việc này. Sau đó, trong cửa sổ cha mẹ bạn đính kèm một trình xử lý để phản ứng với sự kiện đó.

Giải pháp này có lợi thế là không phá vỡ khi trang chứa không chứa trình xử lý tải dự kiến. Nói chung hơn, nó không phải là mối quan tâm của iframe để biết môi trường xung quanh của nó.

Xin lưu ý rằng chúng tôi đang tận dụng sự kiện sẵn sàng DOM để kích hoạt sự kiện - điều này phải phù hợp với hầu hết các trường hợp sử dụng.Nếu không, chỉ cần đính kèm dòng sự kiện kích hoạt sự kiện tải của cửa sổ như vậy:

$(window).on('load', function() { ... }); 
+0

Đây là giải pháp duy nhất có hiệu quả đối với tôi. Tôi từ chối sử dụng một cookie để xử lý việc này. – veksen

33

sử dụng iframe onload event

$('#theiframe').on("load", function() { 
    alert(1); 
}); 
+3

Kể từ JQuery 1.7 (tháng 11 năm 2011), bạn phải sử dụng '$ ('# theiframe'). (" Load ", function())'. – Teepeemm

+5

Không hoạt động với jQuery v2.1.3 –

+4

Điều này dường như không kích hoạt. – Primus202

2

Nếu không có mã trong iframe + Animate:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
<script language="javascript" type="text/javascript"> 

function resizeIframe(obj) { 

    jQuery(document).ready(function($) { 

     $(obj).animate({height: obj.contentWindow.document.body.scrollHeight + 'px'}, 500) 

    }); 

}  
</script> 
<iframe width="100%" src="iframe.html" height="0" frameborder="0" scrolling="no" onload="resizeIframe(this)" > 
Các vấn đề liên quan