بادئ ذي بدء ، يتم تقسيم الاتصالات iframe إلى: التواصل بين المجال والتواصل عبر المجال.
1. التواصل في نفس المجال
يشير ما يسمى بالاتصال بالمجال نفسه إلى iframe المتداخل لصفحة A.HTML تحت http: //localhost/demo/iframe/iframea.html
على سبيل المثال: <iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> تواصل بيانات هاتين الصفحتين. على سبيل المثال ، أريد الاتصال بالوظيفة في صفحة الطفل على الصفحة الأصل A.HTML ، وهو أمر سهل بالنسبة لنا للتفكير في document.getElementById('iframeA').contentWindow.b(); تحت Google ، حيث B هي وظيفة في صفحة الطفل B.HTML. ولكن هناك مشكلة في هذه الدعوة التي كنت أعاني منها لفترة طويلة ، أي منذ أن أبلغت عن مثل هذا الخطأ تحت Firefox ، على النحو التالي:
B ليست وظيفة ، لكنني حددت بوضوح مثل هذه الوظيفة على الصفحة الفرعية ، فلماذا يحدث مثل هذا الخطأ؟ بعد التحليل الدقيق وجوجل ، وجدت أن هناك مشكلة يجب فهمها. عندما لم يتم تحميل iframe ، سأقوم بتنفيذ هذا JS والإبلاغ عن مثل هذا الخطأ. لذلك حاولت استخدام وظيفة iframe.onload تحت Firefox لاختبارها. من المؤكد ، لم يكن هناك خطأ ، كان صحيحًا ، لذلك كنت متأكدًا من أنها كانت هذه المشكلة. لذلك أريد أن أكتب IE و Firefox Google لكتابة وظيفة لتأكيد أن iframe قد تم تحميله! ، في الواقع ، أعط وظيفة رد الاتصال للاتصال بأسلوبنا أعلاه.
بناءً على الأفكار المذكورة أعلاه ، يمكنك كتابة رمز مثل هذا:
<iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> </frame> <div id = "topName"> topndddddddddddddddddddddddddddddddddddddddd </viv> <script> الدالة () {تنبيه ("A") ؛ } var iframe = document.getElementById ('iframea') ؛ iframeisload (iframe ، function () {var obj = document.getElementById ('iframea'). contentWindow ؛ obj.b () ؛}) ؛ دالة iframeisload (iframe ، callback) {if (iframe.attachevent) {iframe.attachevent ('Onload' ، function () {callback && callback () ؛}) ؛ } آخر {iframe.onload = function () {callback && callback () ؛ }}}} </script>رمز B.HTML كما يلي:
var b = function () {Alert ("b") ؛ } من السهل جدًا استدعاء وظيفة الصفحة الأصل على صفحة الطفل. فقط افعل هذا وسيكون على ما يرام ، window.parent.A();
تأخذ صفحة الطفل قيمة عنصر الصفحة الأصل: window.parent.document.getElementById("topName").innerHTML وطرق أخرى.
اثنان: Iframe اتصالات عبر المجال.
ينقسم الوصول إلى المجال المتقاطع من iframe بشكل عام إلى حالتين. الأول هو المجال المتقاطع مع نفس المجال الرئيسي والنطاقات الفرعية المختلفة. النوع الثاني هو: المجالات الرئيسية المختلفة المتقاطعة.
1. إنه مجال متقاطع بين النطاقات الفرعية المختلفة تحت نفس المجال الرئيسي ؛ يمكن حله عن طريق تعيين نفس المجال الرئيسي من خلال document.domain.
إذا كان لدي مجال ABC.Example.com ، فهناك صفحة تسمى ABC.HTML ، ويتم متداخلة مع iframe على الصفحة على النحو التالي: <iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = " ABC.HTML نعلم جميعًا أنه نظرًا لقيود سياسة الأصل من نفس الأصل لمتصفح الأمان ، لا يمكن لـ JS تشغيل صفحات مع منافذ مختلفة تحت بروتوكولات مختلفة تحت مجالات مختلفة ، لذلك يتم حل الوصول عبر المجال. إذا كانت الصفحة الأصل ABC.HTML لديها وظيفة JS: function test(){console.log(1);}; أرغب في استدعاء هذه الوظيفة على الصفحة الفرعية أو استدعاء parent.test(); وبهذه الطريقة ، من خلال النظر إلى المجال المتقاطع تحت Firefox ، فإن الحل هو إضافة document.domain = 'example.com' في الجزء العلوي من كل وظيفة JS ، ويمكن حلها.
رمز ABC.HTML كما يلي:
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display: none ؛"> </frame> // الوظيفة التي تستدعي الصفحة الأصل عبر صفحات المجال الفرعية (على افتراض أنها وظيفة الاختبار أدناه) document.domain = 'example.com' ؛
رمز def.html كما يلي:
/** طريقة صفحة الطفل التي تستدعي الصفحة الأصل*/document.domain = 'example.com' ؛ // window.top.test () ؛ window.parent.test () ؛
أو هاتين الصفحتين ، أريد أن تتصل الصفحة الأصل بصفحة الطفل على النحو التالي:
رمز A.HTML كما يلي:
/*** الوظائف التي تريد الاتصال بصفحات الطفل عبر صفحة الوالدين المجال*/document.domain = 'example.com' ؛ var iframe = document.getElementById ('iframe2') ؛ iframeisload (iframe ، function () {var obj = iframe.contentwindow ؛ obj.child () ؛}} if (iframe.attachevent) {iframe.attachevent ('onload' ، function () {callback && callback () ؛}) ؛ } آخر {iframe.onload = function () {callback && callback () ؛ }}}}إذا كان هناك رمز وظيفة طفل على صفحة def.html الآن:
document.domain = 'example.com' ؛ function child () {console.log ('أنا صفحة طفل') ؛}يمكنك الاتصال عبر المجالات سواء كانت صفحة طفل تتصل بصفحة الأصل أو صفحة الوالدين التي تتصل بصفحة الطفل. كل شيء على ما يرام!
2. إنها المجالات الرئيسية المختلفة والمجالات المتقاطعة.
على الرغم من أن Google لديها عدة طرق لمشكلات النطاق عبر المجالات الرئيسية المختلفة ، بما في ذلك location.hash Method ، window.name Method ، HTML5 و FLASH ، وما إلى ذلك ، أعتقد أن طريقة IFRAME التالية تستحق التعلم.
كما هو موضح في الشكل أدناه: request.html من المجال a.com (أي http://a.com/demo/ajax/ajaxproxy/request.html) متداخل مع iframe يشير إلى المجال b.com (http://b.com/demo/ajaxproxy Domain A.COM متداخل مع proxy.html من المجال A.COM.
IDEA: لتنفيذ صفحة request.html ضمن عملية طلب المجال A.COM. أخيرًا ، نظرًا لأن proxy.html و request.html في نفس المجال ، يمكنك استخدام Window.top لإرجاع النتيجة في request.html لإكمال المجال المتقاطع الحقيقي.
حسنًا ، لنلقي نظرة على بنية الصفحة أولاً
تحت مجال A.COM ، هناك:
request.html
Proxy.html
تحت مجال B.com ، هناك:
استجابة. html
Process.php
دعنا نلقي نظرة على صفحة request.html على النحو التالي:
<! doctype html> <html> <head> <title> مستند جديد </title> </head> <body> <p id = "result" style = "display: none"> </frame> <script> document.getElementById ('sendBtn'). onClick = function () {var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html' ، fn = 'getPerson' ، // this is is is is is an defeld. "{" id ": 24} '، // هذا هو callback parameter المطلوب =" Callback "؛ . // إرسال طلب} دالة CrossRequest (url ، fn ، reqdata ، callback) {var server = document.getElementById ('serverif') ؛ server.src = url + '؟ fn =' + encodeUricomponent (fn) + "& data =" + EncodeUricomponent (reqdata) + "& callback =" + encodeUricomponent (callback) ؛ }. document.getElementById ("النتائج"). innerhtml = str ؛ } </script> </body> </html> تدور هذه الصفحة في الواقع حول إخبار الاستجابة. html: أريدك أن تنفذ الطريقة التي حددتها GetPerson ، واستخدم المعلمة '{"id": 24}' أعطيتك. Response.html مسؤول بحت عن تمرير CallBack اسم الطريقة إلى Brother Proxy.html التالية. يمكن لـ proxy.html تنفيذها بعد الحصول على CallBack اسم الطريقة ، لأن proxy.html و request.html في نفس المجال.
رمز Response.html كما يلي:
<! doctype html> <html> <head> <title> مستند جديد </title> </head> <body> <body> <frame id = "proxy"> </frame> <script> // method general method ajax requred _request (reqdata ، url ، callback) {var xmlhtp ؛ if (window.xmlHttpRequest) {xmlHtp = new xmlHttpRequest () ؛ } else {xmlhttp = new ActivexObject ("Microsoft.xmlHttp") ؛ } xmlHttp.OnReadyStateChange = function () {if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {var data = xmlhttp.responsetext ؛ رد الاتصال (البيانات) ؛ }} xmlhttp.open ('post' ، url) ؛ xmlhttp.setRequestHeader ("نوع المحتوى" ، "التطبيق/json ؛ charset = utf-8") ؛ xmlhttp.send (reqdata) ؛ } // الطريقة العامة للحصول على دالة معلمات url _getQuery (مفتاح) {var query = location.href.split ('؟') [1] ، value = decodeuricomponent (query.split (key + "=") [1] .split ("&") [0]) ؛ قيمة الإرجاع }. var fn = function (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) ؛ } (function () {var fn = _getquery ('fn') ، reqdata = _getquery ("data") ، callback = _getquery ("callback") ؛ eval (fn + "('" + reqdata + "' ، '" + callback + "')") ؛}) ؛ </script> </body> </html>هذا هو في الواقع تلقي الطلب من request.html والحصول على معلمات وطرق الطلب ، ثم إصدار طلب AJAX حقيقي إلى عملية الخادم.
بعد ذلك ، دعونا نلقي نظرة على رمز PHP على النحو التالي ، وهو في الواقع فقط لإرجاع بيانات JSON:
<؟ php $ data = json_decode (file_get_contents ("php: // input")) ؛ header ("نوع المحتوى: application/json ؛ charset = utf-8") ؛ echo ('{"id":'. $ data-> id. '، "Age": 24 ، "Sex": "Boy" ، "Name": "Huangxueming"}') ؛؟>؟أخيرًا ، هناك رمز proxy.html:
<! doctype html> <html> <head> <title> مستند جديد </title> </head> <body> <script> الدالة _geturl (مفتاح) {// general method ، الحصول على معلمات url var query = location.href.split ("؟") ، value = decodeuricombonit "=") [1] .Split ("&") [0]) ؛ قيمة الإرجاع } (function () {var callback = _geturl ("callback") ، data = _geturl ("data") ؛ eval ("window.top. </script> </body> </html>هذه هي أيضا الخطوة الأخيرة. أخيرًا ، حصلت شركة Proxy على اسم وظيفة رد الاتصال المنقولة من request.html من خلال الاستجابة. html وبيانات الاستجابة التي يتم إرسالها مباشرة من reponse.html ، و window.
3. مشكلة عالية التكيف مع الإيفاد.
يتم تقسيم التكيف مع ارتفاع Iframe إلى نوعين: واحد هو التكيف تحت نفس المجال والآخر هو التكيف تحت المجال المتقاطع . دعونا نلقي نظرة على مشكلة التكيف العالي في نفس المجال.
1. مشاكل مع الإطارات القابلة للتكيف للغاية في نفس المجال:
الفكرة: احصل على عنصر iframe المتداخل ، واحصل على الارتفاع النهائي للصفحة المتداخلة عبر JavaScript ، ثم قم بتعيينه على الصفحة الرئيسية لتحقيق ذلك.
إذا كان العرض التجريبي الخاص بنا يحتوي على iframe1.html و iframe2.html
ما يلي هو الرمز التالي:
<! doctype html> <html> <head> <title> مستند جديد </title> <style> *{margin: 0 ؛ padding: 0 ؛} </style> </head> <body> <frame src = "http://a.com/demo/ajax/iframehight/iframe2.html" id = "iframe"> </frame> <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 ؛ } آخر إذا (iframeid.document && iframeid.document.body.scrollheight) {iframeid.height = iframeid.document.body.scrollheight ؛ }}} </script> </body> </html>iframe2.html
<! doctype html> <html> <head> <title> مستند جديد </title> <style> *{margin: 0 ؛ padding: 0 ؛يمكنك ضبط ارتفاع صفحة Iframe1 على ارتفاع Iframe2.
2. iframes قابلة للتكيف بدرجة كبيرة عبر المجالات.
بادئ ذي بدء ، نحن نعلم أنه لا يمكننا التحكم في المجال المتقاطع من IFRAMES مع طريقة JS أعلاه ، لذلك يمكننا فقط استخدام المفتاح الوسيط إلى NEST an iframe2.html page ضمن مجال B.com على صفحة iframe1.html ضمن المجال A.COM. وبهذه الطريقة ، يمكن لـ iframe1.html و iframe3.html التواصل بدون حواجز ، لأن الصفحة iframe2.html تعشف iframe3.html ، لذلك يمكن أن يعيد Iframe2.html إعادة كتابة قيمة HREF لـ iframe3.html.
المحتويات في iframe1:
يقبل محتوى iframe1.html بشكل أساسي المحتوى الذي يتم إرساله من صفحة iframe3.html ويكمل العملية المقابلة. رمز iframe1.html هو كما يلي:
<iframe src = "http://b.com/demo/ajax/iframeheight/iframe2.html" id = "iframe"> </frame> <script> var ifr_el = document.getElementById ("iframe") ؛ وظيفة getifrdata (البيانات) {ifr_el.style.height = data+"px" ؛ } </script>المحتوى في iframe2.html:
كيف يتم نقل محتوى iframe2.html القيمة إلى صفحة iframe3.html؟ قلت للتو إن القيمة يتم تمريرها إلى HREF لصفحة iframe3.html ، لذلك فقط تعديل SRC IFRAME. نظرًا لعدم وجود حاجة لتحديث صفحة C ، يمكن تمريرها إلى صفحة IFRAME3.HTML بواسطة التجزئة. رمز iframe2.html كما يلي:
<! doctype html> <html> <head> <title> مستند جديد </title> <style> *{margin: 0 ؛ padding: 0 ؛ var 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>يمكنك أن ترى ذلك بشكل افتراضي ، ارتفاع صفحة iframe1.html أعطي iframe2.html هو 200 بكسل ، ولكن في iframe2.html أعطي iframe3.html ارتفاع iframe3.html هو 230 بكسل ، لذلك في ظل الظروف العادية ، هناك شريط تمرير. الآن أريد أن أحصل على ارتفاع شريط التمرير في iframe2.html ، تم نقل الارتفاع إلى src من خلال iframe3.html ، ثم الحصول على قيمة الارتفاع في صفحة iframe3.html لتمريرها إلى iframe1.html (لأن Iframe1.html و iframe3.html هي القيمة نفسها). الارتفاع نفسه ، لا بأس.
الوظيفة الوحيدة لصفحة iframe3.html هي تلقي القيمة التي تم تمريرها بواسطة صفحة iframe2.html من خلال HREF ونقلها إلى صفحة iframe1.html. يمكن فحص القيمة التي تم تمريرها إلى صفحة iframe2.html بشكل مستمر من خلال مؤقت لمعرفة ما إذا كان الموقع. href قد تم تغييره ، لكن هذا غير فعال للغاية. هناك طريقة أخرى هي الاستماع إلى تغييرات HREF من خلال حدث onhashchange (IE8+، Chrome5.0+، Firefox3.6+، Safari5.0+، Opera10.6+) في المتصفح الجديد.
رمز iframe3.html كما يلي:
<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.getifrdata (oldheight) ؛ </script>هذا يمكن أن يحل مشكلة تحقيق ارتفاع القدرة على التكيف مع IFrame من خلال المجال المتقاطع.
4. ملخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون ذلك مفيدًا لدراسة الجميع والعمل. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لمناقشة.