IFRAME yüklemesi tamamlandığında Javascript geri araması?


147

Bir IFRAME yüklemeyi bitirdiğinde bir geri arama yürütmem gerekiyor. IFRAME’deki içerik üzerinde hiçbir kontrolüm olmadığı için geri aramayı oradan başlatamam.

Bu IFRAME programla oluşturuldu ve verilerini geri aramada değişken olarak iletmem ve iframe'i yok etmem gerekiyor.

Herhangi bir fikir?

DÜZENLE:

İşte şimdi sahip olduğum şey:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}

İFrame yüklenmeden önce bu geri arama, dolayısıyla geri aramada hiçbir veri döndürülmez.


1
Olay işleyicisini iframe'in kendisine eklemek istemediğinizi düşünüyorum, ancak içerik penceresi.
bobwienholt

1
Sorun, alanlar arası istektir. İframe başka bir etki alanındaysa bunu yapamazsınız
Victor

Aslında, iframe nesnesinde, iframe bir belgeyi yüklemeyi her bitirdiğinde tetiklenen bir yükleme olayı var, aksi takdirde, her yüklemeden sonra pencereye bağlanmanız gerekir
Juan Mendes


Cevabımı burada görün: stackoverflow.com/a/36155560/3894981
ahbap

Yanıtlar:


49

İlk olarak, xssRequest işlev adına giderseniz , siteler arası istek deniyormuşsunuz gibi görünür - bu doğruysa, iframe içeriğini okuyamazsınız.

Öte yandan, iframe'in URL'si alan adınızdaysa gövdeye erişebilirsiniz, ancak iframe'i kaldırmak için bir zaman aşımı kullanırsam geri aramanın iyi çalıştığını gördüm:

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});

4
$('body', this.contentWindow.document).html()ile değiştirebilirsinizthis.contentDocument.body.outerHTML
Sam Soffes

12
Bunu jQuery olmadan nasıl yapacağınıza dair bir fikriniz var mı?
devios1

6
JQuery 3.0'dan itibaren loadgitmiştir. Lütfen .on('load', function() { ... })bunun yerine kullanın.
Doppelganger

36

JQuery kullanıyorum ve şaşırtıcı bir şekilde bu, ağır bir sayfayı test edip yüklediğim için yükleniyor gibi görünüyor ve iframe yükünü görene kadar birkaç saniye uyarı almadım:

$('#the_iframe').load(function(){
    alert('loaded!');
});

Bu nedenle, jQuery'yi kullanmak istemiyorsanız, kaynak kodlarına bir göz atın ve bu işlevin iframe DOM öğeleriyle farklı davranıp davranmadığına bakın, daha sonra ilgilenip burada yayınladığım için ona kendim bakacağım. Ayrıca sadece en son kromda test ettim.


DOM öğesini saf javascript ile oluşturduğunuzu ve sonra bu değişkeni seçici olarak jQuery'ye aktardığınızı fark ettim, belki de kodunuz bu yüzden çalışmıyor?
Neo

12
JQuery 3.0'dan itibaren loadgitmiştir. Lütfen .on('load', function() { ... })bunun yerine kullanın.
Doppelganger

8

İframe etiketiniz üst belgedeki herhangi bir içeriği çevrelemediği için iframe'inizin innerHTML'si boştur. İframe'in src özniteliği tarafından atıfta bulunulan sayfadaki içeriği almak için, iframe'in contentDocument özelliğine erişmeniz gerekir. Ancak src farklı bir etki alanındaysa bir istisna atılır. Bu, başka birinin sayfasında rastgele JavaScript çalıştırmanızı engelleyen ve siteler arası komut dosyası çalıştırma güvenlik açığı oluşturan bir güvenlik özelliğidir. İşte bahsettiğim şeyi gösteren bir örnek kod:

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>

Örneği ilerletmek için, bunu iframe içeriği olarak kullanmayı deneyin:

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>

1
contentDocument özelliği IE 7 tarafından desteklenmiyor ve belki daha fazla IE de desteklenmiyor, IE ile başa çıkmanın yolu window.frames ['iframeid'] ile tam olarak aynı olan window.frames ['iframeid'] . mozilla.org/en/…
Olga

7

Word belgeleri ve pdf'ler gibi belgelerin iframe'e aktarıldığı ve oldukça iyi çalışan bir çözüm bulduğu durumlarda bunu yapmak zorunda kaldım. Anahtar, onreadystatechangediframe üzerindeki olayı işlemektir .

Çerçevenizin adının "iframe" olduğunu söyleyelim. İlk önce kod başlangıcınızda bir yere (iframe'den sonra herhangi bir yerde satır içi yaparım) olay işleyicisini kaydetmek için buna benzer bir şey ekleyin:

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

İframe üzerinde onreadystatechage özniteliğini kullanamadım, nedenini hatırlayamıyorum, ancak uygulamanın IE 7 ve Safari 3'te çalışması gerekiyordu, bu yüzden bu bir faktör olabilir.

İşte tam durumun nasıl alınacağına dair bir örnek:

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}

7

İ frame içeriği IE'ye tam olarak yüklendiğinde bekleyen döndürücü div'i gizlemek istedim, Stackoverflow.Com'da bahsedilen her çözümü tam anlamıyla denedim, ancak hiçbir şey istediğim gibi çalışmadı.

Sonra, i frame içeriği tam olarak yüklendiğinde, $ (Window) load olayının tetiklenebileceğine dair bir fikrim vardı. Ve tam olarak ne oldu. Ben de bu küçük senaryoyu yazdım ve sihir gibi çalıştım:

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });

Bu yardımcı olur umarım.


bu basit bir çözümdür ve javascript'inizin tüm sayfa yüklendikten SONRA yürütülmesini istiyorsanız iyi çalışır. bu, ilk önce js etkisi olmadan tam olarak yüklenmiş sayfayı görmeniz ve belki bir veya iki saniye sonra (yüke bağlı olarak) javascript tarafından oluşturulan değişiklikler o zaman gerçekleşeceği anlamına gelir. Şahsen iframe'imi yeniden boyutlandırmayı denedim ve bir sayfaya tıkladıktan sonra ilk üç saniye ekrana dikkat etmezseniz işe yarıyor, ancak bu (benim durumumda olduğu gibi) koda bir yama olarak görünebilir.
Ve işaretleri

1
Yorumunuz için teşekkür ederim, bu çözüm benim durumumda harika çalıştı, çünkü iframe'in sayfa yüklendikten sonra yüklenmesini istedim.
Nada N. Hantouli

2

Seninle benzer bir sorun yaşadım. Yaptığım şey jQuery adlı bir şey kullanmam. Daha sonra javascript kodunda yaptığınız şey şudur:

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

Görünüşe göre html'yi ondan almadan önce iFrame'inizi siliyorsunuz. Şimdi, bununla ilgili bir sorun görüyorum: p

Bu yardımcı olur umarım :).


1

Projelerimde iyi çalışan benzer bir kodum var. Kodumu işlevinize uyarlamak için bir çözüm şu olabilir:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.id = 'myUniqueID';
    document.body.appendChild(iFrameObj);       
    iFrameObj.src = url;                        

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

Belki boş bir innerHTML'niz olabilir, çünkü (biri veya her ikisi neden olur): 1. Bunu gövde öğesine karşı kullanmalısınız 2. iframe'i sayfanızın DOM'sinden kaldırdınız


1

Yükleme olayının doğru olduğunu düşünüyorum. Doğru olmayan, içeriği iframe içerik alanından almak için kullandığınız yöntemdir.

İhtiyacınız olan şey, iframe'e yüklenen sayfanın html'sidir, iframe nesnesinin html'si değil.

Yapmanız gereken, içerik belgesine ile erişmek iFrameObj.contentDocument. Bu, geçerli sayfanın aynı etki alanındaysa, iframe içine yüklenen sayfanın etki alanını döndürür.

İframe'i kaldırmadan önce içeriği geri alırdım.

Firefox ve operada test ettim.

Daha sonra verilerinizi $(childDom).html()veya ile geri alabileceğinizi düşünüyorum.$(childDom).find('some selector') ...


0

Geçmişte de tamamen aynı sorunu yaşadım ve düzeltmenin tek yolu geri aramayı iframe sayfasına eklemekti. Elbette bu yalnızca iframe içeriği üzerinde kontrolünüz olduğunda çalışır.


22
Size oy vermedim, ancak onun yapamayacağını söylediği şeyi önerdiğiniz için reddedildiğinizi tahmin ediyorum - özellikle, "IFRAME'deki içerik üzerinde hiçbir kontrolüm yok, bu yüzden yapabilirim" dedi. Geri aramayı oradan başlat. "
Dave Haynes

-1

onloadAttrbute kullanmak sorununuzu çözecektir.

İşte bir örnek.

function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>

İstediğiniz bu mu?

Daha fazla bilgi için burayı tıklayın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.