javascript - jQuery .ready dinamik olarak eklenen bir iframe içinde


Birisi bir resme tıkladığında dinamik olarak bir iframe göstermek için jQuery thickbox kullanıyoruz. Bu iframe içinde, birden fazla resmi görüntülemek için bir JavaScript kütüphanesi olan galleria'yı kullanıyoruz.

Sorun, iframe içindeki $ (document).ready işleminin çok erken tetikleniyor gibi görünmesi ve iframe içeriğinin henüz yüklenmemiş olması, bu yüzden galleria kodunun DOM öğeleri üzerinde düzgün bir şekilde uygulanmaması gibi görünüyor. $ (document).ready, iframe'in hazır olup olmadığını belirlemek için iframe üst öğesinin hazır olma durumunu kullanıyor gibi görünüyor.

Document ready ile çağrılan fonksiyonu ayrı bir fonksiyona çıkartır ve onu 100 ms'lik bir zaman aşımından sonra çağırırsak çalışır, ancak üretimde yavaş bir bilgisayarda risk alamayız.

$(document).ready(function() { setTimeout(ApplyGalleria, 100); });

Benim sorum: Dinamik iframe hazır olduğunda ve sadece onun ebeveyni değil, kodumuzu çalıştırabilmek için hangi jQuery olayına bağlanmalıyız?

Cevap #1

Ben benzer bir soruyu yanıtlamıştım (bkz. IFRAME yüklendiğinde Javascript callback?). Aşağıdaki kod ile iframe yükleme olayı üzerinde kontrol sağlayabilirsiniz:

function callIframe(url, callback) {
    $(document.body).append('<IFRAME id="myId" ...>');
    $('iframe#myId').attr('src', url);

    $('iframe#myId').load(function() {
        callback(this);
    });
}

Iframe'lerle uğraşırken, document ready olayını kullanmak yerine load olayını kullanmanın yeterince iyi olduğunu gördüm.

Cevap #2

jQuery 1.3.2 kullanarak, aşağıdaki benim için işe yaradı:

$('iframe').ready(function() {
  $('body', $('iframe').contents()).html('Hello World!');
});

DÜZELTME:! Aslında yukarıdaki kod bazen Firefox'ta çalışıyor gibi görünüyor, Opera'da hiçbir zaman çalışıyormuş gibi görünmüyor.

Bunun yerine amaçlarım için bir yoklama çözümü uyguladım. Basitleştirilmiş haliyle şöyle görünüyor:

$(function() {
  function manipIframe() {
    el = $('body', $('iframe').contents());
    if (el.length != 1) {
      setTimeout(manipIframe, 100);
      return;
    }
    el.html('Hello World!');
  }
  manipIframe();
});

Bu, çağrılan iframe sayfalarında kod gerektirmez. Tüm kod, üst çerçeveden/pencereden bulunur ve çalıştırılır.

Cevap #3

IFrame'larda genellikle bu problemi, küçük bir script'i bloğun en sonuna koyarak çözerim:

<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
   fireOnReadyEvent();
   parent.IFrameLoaded();
//]]>
</script>
</body>

Bu çoğu zaman benim için işe yarıyor. Bazen en basit ve en saf çözüm en uygun olanıdır.

İlgili makaleler