Pertama-tama, komunikasi iframe dibagi menjadi: komunikasi domain yang sama dan komunikasi lintas domain.
1. Komunikasi dalam domain yang sama
Komunikasi domain yang sama yang disebut mengacu pada iframe nested dari halaman A.html di bawah http: //localhost/demo/iframe/iframea.html
Sebagai contoh: <iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> Data dari dua halaman ini berkomunikasi. Misalnya, saya ingin memanggil fungsi di halaman anak di halaman induk A.html, yang mudah bagi kita untuk memikirkan document.getElementById('iframeA').contentWindow.b(); Di bawah Google, di mana B adalah fungsi di halaman anak B.html. Tetapi ada masalah dengan panggilan ini yang telah saya perjuangkan untuk waktu yang lama, yaitu, karena saya telah melaporkan kesalahan seperti itu di bawah Firefox, sebagai berikut:
B bukan fungsi, tetapi saya dengan jelas mendefinisikan fungsi seperti itu pada subpage, jadi mengapa kesalahan seperti itu terjadi? Setelah analisis yang cermat dan Google, saya menemukan bahwa ada masalah yang perlu dipahami. Ketika iframe belum dimuat, saya akan menjalankan JS ini dan melaporkan kesalahan seperti itu. Jadi saya mencoba menggunakan fungsi iframe.onload di bawah Firefox untuk mengujinya. Benar saja, tidak ada kesalahan, itu benar, jadi saya yakin itu masalah ini. Jadi saya ingin menulis IE dan Firefox Google yang kompatibel untuk menulis fungsi untuk mengonfirmasi bahwa iframe telah dimuat! , pada kenyataannya, berikan fungsi panggilan balik untuk memanggil metode kami di atas.
Berdasarkan ide -ide di atas, Anda dapat menulis kode seperti ini:
<iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> </iframe> <Div id = "TopName"> TOPNDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD </DIV> <Pript> function a () {waspada ("a"); } var iframe = document.getElementById ('iframea'); iframeisload (iframe, function () {var obj = document.geteLementById ('iframea'). ContentWindow; obj.b ();}); function iframeisload (iframe, callback) {if (iframe.attachevent) {iframe.attachevent ('onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}} </script>Kode B.html adalah sebagai berikut:
var b = function () {alert ("b"); } Sangat mudah untuk memanggil fungsi halaman induk di halaman anak. Lakukan saja ini dan akan baik -baik saja, window.parent.A();
Halaman anak mengambil nilai elemen halaman induk: window.parent.document.getElementById("topName").innerHTML dan metode lainnya.
Dua: komunikasi lintas domain iframe.
Akses cross-domain iframe umumnya dibagi menjadi dua situasi. Yang pertama adalah domain silang dengan domain utama yang sama dan subdomain yang berbeda. Tipe kedua adalah: domain domain utama yang berbeda.
1. Ini adalah domain silang antara subdomain yang berbeda di bawah domain utama yang sama; itu dapat diselesaikan dengan mengatur domain utama yang sama melalui document.domain.
Jika saya memiliki domain abc.example.com, ada halaman yang disebut abc.html, dan iframe bersarang di halaman sebagai berikut: <iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "non tidak ada;" Halaman ABC.html Kita semua tahu bahwa karena keterbatasan kebijakan asal-kata dari browser keamanan, JS tidak dapat mengoperasikan halaman dengan port yang berbeda di bawah protokol yang berbeda di bawah domain yang berbeda, sehingga akses lintas domain diselesaikan. Jika halaman induk abc.html memiliki fungsi JS: function test(){console.log(1);}; Saya ingin memanggil fungsi ini pada subpage atau call parent.test(); Dengan cara ini, dengan melihat domain silang di bawah Firefox, solusinya adalah menambahkan document.domain = 'example.com' di bagian atas setiap fungsi JS, dan dapat diselesaikan.
Kode ABC.html adalah sebagai berikut:
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display: none;"> </iframe> // fungsi yang memanggil halaman induk di seluruh subpag domain (dengan asumsi itu adalah fungsi uji di bawah) dokumen.
Kode def.html adalah sebagai berikut:
/** Metode halaman anak yang memanggil halaman induk*/document.domain = 'example.com'; // window.top.test (); window.parent.test ();
Atau dua halaman ini, saya ingin halaman induk memanggil halaman anak sebagai berikut:
Kode A.html adalah sebagai berikut:
/** Fungsi yang ingin memanggil halaman anak di halaman induk domain*/document.domain = 'example.com'; var iframe = document.getElementById ('iframe2'); iframeisload (iframe, function () {var obj = iframe.contentWindow; obj.child (); function); if (iframe.attachevent) {iframe.attachevent ('onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}}Jika ada kode fungsi anak pada halaman def.html sekarang:
document.domain = 'example.com'; function child () {console.log ('I Am a Child Page');}Anda dapat menelepon lintas domain apakah itu halaman anak yang menelepon halaman induk atau halaman induk yang menelepon halaman anak. Semuanya baik -baik saja!
2. Ini adalah domain utama dan domain silang yang berbeda;
Meskipun Google memiliki beberapa metode untuk masalah lintas domain pada domain utama yang berbeda, termasuk metode location.hash , metode window.name , html5 dan flash, dll., Saya pikir metode iframe berikut layak dipelajari.
Seperti yang ditunjukkan pada gambar di bawah ini: halaman permintaan.html dari domain A.com (mis. Domain A.com bersarang dengan proxy.html dari domain A.com.
Ide: Untuk mengimplementasikan halaman permintaan.html di bawah proses permintaan domain A.com.php di bawah domain b.com, Anda dapat meneruskan parameter permintaan ke respons.html melalui url, dan memulai permintaan AJAX yang nyata dari respons.html untuk memproses. Akhirnya, karena proxy.html dan request.html berada di domain yang sama, Anda dapat menggunakan window.top untuk mengembalikan hasilnya dalam permintaan.html untuk menyelesaikan domain silang yang sebenarnya.
Oke, mari kita lihat struktur halaman terlebih dahulu
Di bawah domain A.com, ada:
request.html
proxy.html
Di bawah domain b.com, ada:
response.html
Process.php
Mari kita lihat halaman permintaan.html sebagai berikut:
<! Doctype html> <html> <head> <title> dokumen baru </itement> </head> <b body> <p id = "hasil"> hasil respons akan diisi di sini </p> <a id = "sendbtn" href = "ifrcript: void (0)"> Klik untuk mengirim permintaan silang </a> </a> </a> </a "<" ID = ": tidak ada </a". <script> document.geteLementById ('sendbtn'). onclick = function () {var url = 'http://b.com/demo/ajax/Ajaxproxy/reponse.html', fn = 'getperson', // Ini adalah metode yang didefinisikan sebagai respon.html reqdon '{' {'{' {'{' {'html' parameter callback = "callback"; // Ini adalah fungsi panggilan balik yang dieksekusi setelah seluruh proses permintaan selesai, melaksanakan tindakan terakhir CrossRequest (URL, FN, Reqdata, Callback); // Kirim permintaan} function crossRequest (url, fn, reqdata, callback) {var server = document.geteLementById ('serverif'); server.src = url + '? fn =' + encodeuricomponent (fn) + "& data =" + encodeuricomponent (reqdata) + "& callback =" + encodeuricomponent (callback); } // fungsi callback fungsi callback (data) {var str = "nama saya adalah" + data.name + ". Saya adalah" + data.sex + ". Saya" + data.age + "tahun."; document.geteLementById ("hasil"). innerHtml = str; } </script> </body> </html> Halaman ini sebenarnya tentang memberi tahu respons.html: Saya ingin Anda menjalankan metode yang Anda definisikan GetPerson , dan gunakan parameter '{"id": 24}' Saya berikan kepada Anda. response.html murni bertanggung jawab untuk meneruskan metode CallBack metode ke saudara proxy.html saudara berikutnya. Proxy.html dapat menjalankannya setelah mendapatkan CallBack nama metode, karena proxy.html dan request.html berada di domain yang sama.
Kode respons.html adalah sebagai berikut:
<! Doctype html> <html> <head> <title> dokumen baru </iteme> </head> <body> <iframe id = "proxy"> </iframe> <script> // Metode Umum Permintaan AJAX _Request (reqdata, url, callback) {var xmlhtp; if (window.xmlHttpRequest) {xmlhttp = new xmlHttpRequest (); } else {xmlhttp = new ActiveXObject ("microsoft.xmlhttp"); } xmlhttp.onreadystatechange = function () {if (xmlhttp.readystate == 4 && xmlhttp.status == 200) {var data = xmlhttp.responsetext; panggilan balik (data); }} xmlhttp.open ('pos', url); xmlhttp.setRequestHeader ("tipe konten", "aplikasi/json; charset = utf-8"); xmlhttp.send (reqdata); } // Metode umum untuk mendapatkan fungsi parameter URL _getQuery (key) {var query = location.href.split ('?') [1], value = decodeuricomponent (query.split (key + "=") [1] .split ("&") [0]); nilai pengembalian; } // Kirim permintaan AJAX ke function.php function getperson (reqdata, callback) {var url = 'http://b.com/demo/ajax/ajaxproxy/process.php'; var fn = fungsi (data) {var proxy = document.geteLementById ('proxy'); proxy.src = "http://a.com/demo/ajax/ajaxproxy/proxy.html?data=" + encodeuricomponent (data) + "& callback =" + encodeuricomponent (callback); }; _Request (reqdata, url, fn); }; </script> </body> </html>Ini sebenarnya untuk menerima permintaan dari permintaan.html dan mendapatkan parameter dan metode permintaan, dan kemudian mengeluarkan permintaan AJAX nyata ke proses server.php, dan kemudian lulus data yang dikembalikan dari server dan nama fungsi callback yang diteruskan dari permintaan.html ke proxy.html.
Selanjutnya, mari kita lihat kode PHP sebagai berikut , yang sebenarnya hanya untuk mengembalikan data JSON:
<? php $ data = json_decode (file_get_contents ("php: // input")); header ("tipe konten: aplikasi/json; charset = utf-8"); echo ('{"id":'. $ data-> id. ', "Age": 24, "Sex": "Boy", "Name": "Huangxueming"}');?>Akhirnya, ada kode proxy.html:
<! Doctype html> <html> <head> <title> dokumen baru </iteme> </head> <body> <script> fungsi _getUrl (key) {// Metode umum, dapatkan parameter url var kueri = lokasi.href.split ("?") [1], value = decodeuricomponent (query.split (query. "=") [1] .split ("&") [0]); nilai pengembalian; } (function () {var callback = _getUrl ("callback"), data = _getUrl ("data"); eval ("window.top." + decodeuricomponent (callback) + "(" + decodeuricomponent (data) + "));}) (); </script> </body> </html>Ini juga langkah terakhir. Proxy akhirnya mendapatkan nama fungsi panggilan balik yang dikirimkan dari permintaan.html melalui response.html dan data respons yang dikirimkan langsung dari response.html, dan menggunakan window.top untuk menjalankan fungsi callback yang ditentukan dalam request.html.
3. Masalah adaptasi tinggi iframe.
Adaptasi tinggi iframe dibagi menjadi dua jenis: satu adalah adaptasi di bawah domain yang sama dan yang lainnya adalah adaptasi di bawah domain silang . Mari kita lihat masalah adaptasi tinggi di domain yang sama.
1. Masalah dengan iframes yang sangat mudah beradaptasi di domain yang sama:
Ide: Dapatkan elemen iframe bersarang, dapatkan ketinggian akhir dari halaman bersarang melalui JavaScript, dan kemudian atur di halaman utama untuk mencapainya.
Jika demo kami memiliki iframe1.html dan iframe2.html
Berikut ini adalah kode berikut:
<! Doctype html> <html> <head> <title> dokumen baru </itement> <tyle> *{margin: 0; padding: 0;} </tyle> </demo/ajax/iframe src = "http://a.com/demo/ajax/iframeHeight/ifrrame2.htmo =" "" id = "iframe"> </iframe> <script> window.onload = function () {var iframeid = document.getElementById ('iframe'); if (iframeid &&! window.opera) {if (iframeid.contentDocument && iframeid.contentdocument.body.offsetheight) {iframeid.height = iframeid.contentdocument.body.offsetheight; } else if (iframeid.document && iframeid.document.body.scrollheight) {iframeid.height = iframeid.document.body.scrollheight; }}} </script> </body> </html>iframe2.html
<! Doctype html> <html> <head> <title> dokumen baru </itement> <tyle> *{margin: 0; padding: 0;} </tyle> </head> <body> <v style = "tinggi: 500px;"> </div> </body> </html>Anda dapat secara dinamis mengatur ketinggian halaman IFRAME1 ke ketinggian IFRAME2.
2. Iframes sangat mudah beradaptasi di seluruh domain.
Pertama-tama, kita tahu bahwa kita tidak dapat mengontrol domain silang iframes dengan metode JS di atas, jadi kita hanya dapat menggunakan kunci menengah untuk menyarangkan iframe2.html halaman di bawah domain b.com pada halaman iframe1.html dengan domain. Dengan cara ini, iframe1.html dan iframe3.html dapat berkomunikasi tanpa hambatan, karena halaman iframe2.html bersarang iframe3.html, jadi iframe2.html dapat menulis ulang nilai href iframe3.html.
Isi di IfRame1:
Konten IFRAME1.html terutama menerima konten yang dikirimkan dari halaman IFRAME3.html dan menyelesaikan operasi yang sesuai. Kode IFRame1.html adalah sebagai berikut:
<iframe src = "http://b.com/demo/ajax/iframeHeight/iframe2.html" id = "iframe"> </iframe> <script> var ifr_el = document.getElementById ("iframe"); fungsi getifrdata (data) {ifr_el.style.height = data+"px"; } </script>Konten di iframe2.html:
Bagaimana konten iframe2.html meneruskan nilai ke halaman iframe3.html? Saya baru saja mengatakan bahwa nilainya diteruskan ke HREF dari halaman IFRAME3.HTML, jadi cukup ubah SRC IFRAME. Karena tidak perlu menyegarkan halaman C, itu dapat diteruskan ke halaman iframe3.html dengan hash. Kode iframe2.html adalah sebagai berikut:
<! Doctype html> <html> <head> <title> dokumen baru </iteme> <tyle> *{margin: 0; padding: 0;} </tyle> </head> <body> <iframe id = "iframe" src = "http://a.com/demo/ajax/iframe =" http://a.com/demo/ajax/ifram = oldheight = 0, ifr_el = document.geteLementById ("iframe"); t && clearInterval (t); var t = setInterVal (function () {var height = document.body.scrollHeight; if (oldheight! = height) {oldheight = height; ifr_el.src += '#' +oldheight;}}, 200); </script> </body> </html>Anda dapat melihat itu secara default, ketinggian halaman iframe1.html yang saya berikan iframe2.html adalah 200 piksel, tetapi di iframe2.html saya berikan iframe3.html ketinggian iframe3.html adalah 230 piksel, jadi dalam keadaan normal ada bilah gulir. Now I want to get the height of the scroll bar in iframe2.html, pass the height to the src through iframe3.html, and then get the height value in the iframe3.html page to pass it to iframe1.html (because iframe1.html and iframe3.html are in the same domain), so iframe1.html can get this height value, and then set the tinggi itu sendiri, tidak apa -apa.
Satu -satunya fungsi dari halaman iframe3.html adalah menerima nilai yang dilewati oleh halaman iframe2.html melalui href dan meneruskannya ke halaman iframe1.html. Nilai yang diteruskan ke halaman iframe2.html dapat diperiksa terus menerus melalui timer untuk melihat apakah lokasi. HREF telah diubah, tetapi ini terasa sangat tidak efisien. Cara lain adalah mendengarkan perubahan HREF melalui acara onhashchange (IE8+, Chrome5.0+, Firefox3.6+, Safari5.0+, Opera10.6+) di browser baru.
Kode iframe3.html adalah sebagai berikut:
<script> var oldheight = 0; t && clearInterval (t); var t = setInterval (function () {var height = location.href.split ('#') [1]; if (height && height! = oldheight) {oldheight = height; if (window.parent.parent.getifrdata) {window.parent.parent.parent.getifrdata (oldheight); </script>Ini dapat menyelesaikan masalah mencapai ketinggian iframe adaptability melalui domain silang.
4. Ringkasan
Di atas adalah seluruh konten artikel ini. Saya berharap ini akan membantu untuk belajar dan bekerja semua orang. Jika Anda memiliki pertanyaan, silakan tinggalkan pesan untuk didiskusikan.