Mendeteksi ketika konten Iframe telah dimuat (Lintas browser)

91

Saya mencoba mendeteksi ketika iframe dan kontennya dimuat tetapi tidak terlalu beruntung. Aplikasi saya mengambil beberapa masukan di bidang teks di jendela induk dan memperbarui iframe untuk memberikan 'pratinjau langsung'

Saya mulai dengan kode berikut (YUI) untuk mendeteksi saat peristiwa pemuatan iframe terjadi.

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

'preview-pane' adalah ID dari iframe saya dan saya menggunakan YUI untuk melampirkan event handler. Namun, mencoba mengakses tubuh di callback saya (saat memuat iframe) gagal, saya pikir karena iframe dimuat sebelum event handler siap. Kode ini berfungsi jika saya menunda pemuatan iframe dengan membuat skrip php yang membuatnya tidur.

Pada dasarnya, saya bertanya apa pendekatan yang benar di seluruh browser untuk mendeteksi ketika iframe telah dimuat dan dokumennya siap?

David Snabel-Caunt
sumber
1
Memulai dengan YUI adalah ide yang buruk (serta library JS lainnya). Mengapa? Karena Anda tidak bisa mengetahui keajaiban apa yang dilakukan perpustakaan itu. Jika mereka tidak dapat mendukung "memuat" sepenuhnya, Anda sebaiknya melakukannya sendiri dalam javascript yang jelas dan dapat dibaca.
Christian
2
Anda sering dapat membaca kode sumber pustaka @Christian. Saya menemukan ini biasanya memberi Anda tip bagus tentang bagaimana melakukannya sendiri terlepas dari apakah Anda kemudian menggunakan penerapannya atau tidak.
AJP
@AJP Anda salah mengerti maksud saya. Jika Anda melakukan sesuatu yang tidak Anda yakini, lebih baik kurangi kode sehingga lebih sedikit ruang untuk kesalahan.
Kristen
2
Tergantung bagaimana Anda melihatnya. Saya tahu bahwa penanganan acara YUI berfungsi pada saat itu, jadi saya tidak perlu khawatir tentang bagian kode itu. Saya juga tahu bagaimana menulis handler addEvent saya sendiri, tidak bekerja lebih baik dari YUI terkait dengan masalah ini.
David Snabel-Caunt
1
@Nico Pertanyaan merujuk ke YUI dan $ adalah alias untuk pembungkus Dom YUI.
David Snabel-Caunt

Jawaban:

73

mendeteksi kapan iframe telah dimuat dan dokumennya siap?

Ini ideal jika Anda bisa mendapatkan iframe untuk memberi tahu Anda sendiri dari skrip di dalam bingkai. Misalnya itu bisa memanggil fungsi induk secara langsung untuk memberi tahu itu sudah siap. Perawatan selalu diperlukan dengan eksekusi kode lintas frame karena hal-hal dapat terjadi dalam urutan yang tidak Anda harapkan. Alternatif lain adalah menyetel 'var isready = true;' dalam cakupannya sendiri, dan memiliki skrip induk mengendus untuk 'contentWindow.isready' (dan menambahkan handler onload jika tidak).

Jika karena alasan tertentu tidak praktis untuk membuat dokumen iframe bekerja sama, Anda memiliki masalah perlombaan beban tradisional, yaitu meskipun elemennya tepat bersebelahan:

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

tidak ada jaminan bahwa item tersebut belum dimuat pada saat skrip dijalankan.

Cara keluar dari balapan beban adalah:

  1. di IE, Anda dapat menggunakan properti 'readyState' untuk melihat apakah ada sesuatu yang sudah dimuat;

  2. jika memiliki item yang hanya tersedia dengan JavaScript diaktifkan dapat diterima, Anda dapat membuatnya secara dinamis, menyetel fungsi peristiwa 'onload' sebelum menyetel sumber dan menambahkan ke halaman. Dalam kasus ini, ini tidak dapat dimuat sebelum callback disetel;

  3. cara lama untuk memasukkannya ke dalam markup:

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

Penangan 'online' inline di HTML hampir selalu merupakan hal yang salah dan harus dihindari, tetapi dalam kasus ini terkadang itu adalah opsi yang paling tidak buruk.

bobince
sumber
Terima kasih. Solusi saya memeriksa readyState (jika ada), maka panjang elemen tubuh innerHTML untuk melihat apakah telah dimuat. Jika tidak, pasang penangan kejadian beban. Tampaknya bekerja dengan baik
David Snabel-Caunt
8
-1 - peristiwa sebaris tidak "buruk", itu hanya mode saat ini. Faktanya, kejadian sebaris lebih mudah untuk di-debug dan dipahami, tidak seperti kejadian ajaib (yang, di sisi lain, lebih mudah dipasang, ditumpuk, dan digunakan dengan mulus).
Christian
1
@Christian, acara inline juga merupakan opsi terbaik saat Anda perlu melampirkan acara ke setiap elemen dari daftar yang sangat panjang. Karena Anda sudah mengulang untuk membuat daftar di sisi server, jauh lebih efisien untuk melampirkan acara-inline juga.
haknick
16
@haknick Tidakkah Anda ingin menggunakan satu event listener di daftar, dan menggunakan event delegate? Ini akan lebih efisien.
David Snabel-Caunt
4
Ini tidak akan berfungsi jika iframe adalah lintas-domain. Skrip di dalam iframe tidak dapat mengakses jendela induk.
Sudheer Someshwara
48

Lihat postingan blog ini . Ini menggunakan jQuery, tetapi itu akan membantu Anda bahkan jika Anda tidak menggunakannya.

Pada dasarnya Anda menambahkan ini ke file document.ready()

$('iframe').load(function() {
    RunAfterIFrameLoaded();
});
kgiannakakis
sumber
Menarik, tetapi masalah yang saya miliki adalah dengan peristiwa dan waktu muat. Saya mendengarkan acara pemuatan seperti yang disarankan oleh artikel itu.
David Snabel-Caunt
saya telah mencoba ini dengan console.log. itu akan dicatat setelah iframe dimuat.
shorif2000
12

Bagi mereka yang menggunakan React, mendeteksi peristiwa pemuatan iframe asal yang sama semudah menyetel onLoadevent listener pada elemen iframe.

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

Farzad YZ
sumber
Bisakah onLoadperistiwa hanya dapat memicu iframe asal yang sama?
L_K
2

Untuk siapa pun yang menggunakan Ember, ini akan berfungsi seperti yang diharapkan:

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