javascript - لديك - مشاريع جافا سكريبت




استدعاء شفرة جافا سكريبت في iframe من الصفحة الرئيسية (12)

في الأساس ، لدي iframe مضمن في صفحة ، ويحتوي iframe على بعض إجراءات JavaScript أحتاجها للاحتفاظ بها من الصفحة الرئيسية.

أما الآن فالعكس بسيط للغاية حيث أنك تحتاج فقط إلى استدعاء parent.functionName() ، ولكن للأسف ، أحتاج إلى عكس ذلك تمامًا.

يرجى ملاحظة أن مشكلتي لا تغير URL المصدر iframe ، بل تستدعي وظيفة محددة في iframe .


إذا أردنا استدعاء وظيفة javascript للصفحة الرئيسية من iframe الذي تم إنشاؤه من الترميز. shadowbox السابقين أو العلبة الخفيفة

window.parent.targetFunction ()؛


إذا كان iFrame والمستند المحتوي على نطاق مختلف ، فقد لا تعمل الطرق التي تم نشرها مسبقًا ، ولكن يوجد حل:

على سبيل المثال ، إذا كان المستند A يحتوي على عنصر iframe يحتوي على المستند B ، والنص البرمجي في المستند A يستدعي postMessage () على كائن النافذة من المستند B ، فسيتم تشغيل حدث رسالة على هذا الكائن ، يتم وضع علامة على أنها ناشئة من نافذة المستند A. قد يبدو النص البرمجي في المستند A:

var o = document.getElementsByTagName('iframe')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');

لتسجيل معالج أحداث للأحداث الواردة ، قد يستخدم البرنامج النصي addEventListener () (أو آليات مشابهة). على سبيل المثال ، قد يبدو النص البرمجي في المستند B كما يلي:

window.addEventListener('message', receiver, false);
function receiver(e) {
  if (e.origin == 'http://example.com') {
    if (e.data == 'Hello world') {
      e.source.postMessage('Hello', e.origin);
    } else {
      alert(e.data);
    }
  }
}

يقوم هذا البرنامج النصي أولاً بالتحقق من أن المجال هو المجال المتوقع ، ثم ينظر إلى الرسالة التي يعرضها إما للمستخدم ، أو يستجيب لها عن طريق إرسال رسالة إلى المستند الذي أرسل الرسالة في المقام الأول.

عبر http://dev.w3.org/html5/postmsg/#web-messaging


افرج نيتين بانسال الجواب

ولمزيد من المتانة:

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}

و

...
var el = document.getElementById('targetFrame');

getIframeWindow(el).targetFunction();
...

حاول فقط parent.myfunction()


في IFRAME ، اجعل وظيفتك عامة لكائن النافذة:

window.myFunction = function(args) {
   doStuff();
}

للوصول من الصفحة الرئيسية ، استخدم هذا:

var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);

كان Quirksmode وظيفة على هذا .

نظرًا لأن الصفحة معطلة حاليًا ولا يمكن الوصول إليها إلا من خلال archive.org ، فقد أعدت نسخها هنا:

ب IFrames

في هذه الصفحة ، أعطي لمحة عامة عن الوصول إلى iframes من الصفحة التي توجد بها. ليس من المستغرب ، هناك بعض الاعتبارات المتصفح.

إن iframe هو إطار مضمَّن ، ومع ذلك يحتوي الإطار على صفحة منفصلة تمامًا مع عنوان URL الخاص به ، إلا أنه يتم وضعه داخل صفحة HTML أخرى. هذا يعطي إمكانات جميلة جدا في تصميم الويب. تكمن المشكلة في الوصول إلى iframe ، على سبيل المثال لتحميل صفحة جديدة فيه. تشرح هذه الصفحة كيفية القيام بذلك.

الإطار أو الكائن؟

السؤال الأساسي هو ما إذا كان iframe يُنظر إليه كإطار أو ككائن.

  • كما هو موضح في مقدمة إلى صفحات الإطارات ، إذا كنت تستخدم الإطارات ، يقوم المتصفح بإنشاء تسلسل هرمي top.frames[1].frames[2] لك ( top.frames[1].frames[2] و هكذا). هل يتوافق إطار iframe مع هذا الإطار الهرمي؟
  • أو هل يرى المتصفح إطار iframe كشيء آخر فقط ، أي كائن يحدث له خاصية src؟ في هذه الحالة ، يتعين علينا استخدام استدعاء DOM قياسي (مثل document.getElementById('theiframe')) للوصول إليه. في المتصفحات العامة ، تسمح كل من كليتي العرض على إطارات iframe "الحقيقية" (الثابتة) ، ولكن لا يمكن الوصول إلى إطارات iframe كإطارات.

سمة NAME

القاعدة الأكثر أهمية هي إعطاء أي iframe إنشاء سمة name ، حتى إذا كنت تستخدم id أيضًا.

<iframe src="iframe_page1.html"
    id="testiframe"
    name="testiframe"></iframe>

تحتاج معظم المتصفحات إلى سمة name لجعل الجزء iframe من التسلسل الهرمي للإطار. تحتاج بعض المتصفحات (خصوصًا Mozilla) إلى id لجعل iframe قابل للوصول ككائن. من خلال تعيين كلتا الخواص المميزة إلى iframe ، فإنك تحتفظ بخياراتك مفتوحة. لكن name أهم بكثير من الاسم.

التمكن من

إما أن تدخل إلى iframe ككائن وتغيير src أو يمكنك الوصول إلى iframe كإطار وتغيير location.href .

document.getElementById ('iframe_id'). src = 'newpage.html'؛ الإطارات ['iframe_name']. location.href = 'newpage.html'؛ بناء الجملة في الإطار مفضل قليلاً لأن Opera 6 يدعمه ولكن ليس بنية الكائن.

الوصول إلى iframe

لذلك ، للحصول على تجربة كاملة عبر المتصفح ، يجب أن تعطي اسم iframe اسمًا وتستخدم فيه

frames['testiframe'].location.href

بناء الجملة. بقدر ما أعرف هذا يعمل دائما.

الوصول إلى المستند

إن الوصول إلى المستند داخل iframe بسيط للغاية ، بشرط أن تستخدم سمة name . لحساب عدد الارتباطات الموجودة في المستند في iframe ، قم بعمل frames['testiframe'].document.links.length .

الإطارات المضمّنة

عندما تقوم بتوليد iframe خلال W3C DOM ، لا يتم إدخال iframe مباشرة في مصفوفة frames ، مع ذلك ، frames['testiframe'].location.href لن يعمل بناء الجملة frames['testiframe'].location.href الفور. يحتاج المتصفح إلى وقت قليل قبل أن يظهر iframe في الصفيف ، والوقت الذي لا يتم تشغيل أي برنامج نصي فيه.

إن document.getElementById('testiframe').src تعمل بشكل جيد في كل الظروف.

لا تعمل سمة target لرابط إما مع إطارات iframes التي تم إنشاؤها ، باستثناء Opera ، على الرغم من أنني أعطيت iframe المضمن name id .

يعني نقص الدعم target أنه يجب عليك استخدام جافا سكريبت لتغيير محتوى إطار iframe الذي تم إنشاؤه ، ولكن بما أنك تحتاج إلى JavaScript على أي حال لتوليده في المقام الأول ، فأنا لا أرى هذا كمشكلة كبيرة.

حجم النص في iframe

مستكشف غريب 6 علة فقط:

عند تغيير حجم النص من خلال القائمة عرض ، يتم تغيير أحجام النص في iframes بشكل صحيح. ومع ذلك ، لا يغير هذا المستعرض فواصل الأسطر في النص الأصلي ، بحيث يصبح جزء من النص غير مرئي ، أو قد تحدث فواصل أسطر بينما لا يزال الخط يحمل كلمة أخرى.


لقد وجدت حلًا رائعًا.

كما قلت ، من السهل جدًا تنفيذ التعليمة البرمجية الموجودة في المستند الأصلي. وهذه هي قاعدة الكود ، افعل العكس تماماً.

عندما يتم تحميل iframe ، أقوم باستدعاء دالة موجودة في المستند الأصل ، وتمريرها كوسيطة كمرجع لوظيفة محلية ، موجودة في مستند iframe. يحتوي المستند الأصل الآن على وصول مباشر إلى وظيفة iframe من خلال هذا المرجع.

مثال:

على الوالد:

function tunnel(fn) {
    fn();
}

على iframe:

var myFunction = function() {
    alert("This work!");
}

parent.tunnel(myFunction);

عند تحميل iframe ، سيتم استدعاء parent.tunnel (YourFunctionReference) ، والذي سيقوم بتنفيذ الوظيفة المستلمة في المعلمة.

هذا بسيط ، دون الحاجة إلى التعامل مع جميع الأساليب غير القياسية من المتصفحات المختلفة.


مع استمرار جواب :

لمزيد من المتانة ، استخدم كالتالي:

var el = document.getElementById('targetFrame');

if(el.contentWindow)
{
   el.contentWindow.targetFunction();
}
else if(el.contentDocument)
{
   el.contentDocument.targetFunction();
}

workd مثل سحر :)


نفس الأشياء ولكن طريقة أسهل قليلاً هي كيفية تحديث الصفحة الرئيسية من الصفحة داخل iframe . ما عليك سوى استدعاء وظيفة الصفحة الرئيسية لاستدعاء وظيفة جافا سكريبت لإعادة تحميل الصفحة:

window.location.reload();

أو افعل ذلك مباشرة من الصفحة في iframe:

window.parent.location.reload();

كلاهما يعمل.


هناك بعض المراوغات لتكون على بينة من هنا.

  1. ربما يكون HTMLIFrameElement.contentWindow الطريقة الأسهل ، ولكنها ليست خاصية قياسية تمامًا ولا تدعمها بعض المتصفحات ، ومعظمها أقدم منها. هذا لأن معيار DOM المستوى 1 HTML ليس لديه ما يقوله عن كائن window .

  2. يمكنك أيضًا تجربة HTMLIFrameElement.contentDocument.defaultView ، والذي يسمح به بعض المتصفحات القديمة ولكن لا يعمل المتصفح IE. ومع ذلك ، فإن المعيار لا ينص صراحة على استرجاع كائن window ، لنفس السبب (1) ، ولكن يمكنك اختيار بعض إصدارات المتصفح الإضافية هنا إذا كنت تهتم.

  3. window.frames['name'] إعادة النافذة هي أقدم واجهة وبالتالي فهي أكثر موثوقية. ولكن يجب عليك بعد ذلك استخدام خاصية name="..." لتكون قادرة على الحصول على إطار بالاسم ، وهو قبيح / موقوف / انتقالي. ( id="..." سيكون أفضل ولكن IE لا تحب ذلك.)

  4. window.frames[number] موثوق بها للغاية ، ولكن معرفة المؤشر الصحيح هو الخدعة. يمكنك الابتعاد مع هذا على سبيل المثال. إذا كنت تعرف أنك تملك إطار iframe واحد فقط على الصفحة.

  5. من المحتمل تمامًا أن يكون iframe الطفل لم يتم تحميله بعد ، أو حدث خطأ آخر لجعله غير ممكن الوصول إليه. قد تجد أنه من الأسهل عكس تدفق الاتصالات: أي أن يكون iframe التابع للأطفال قد قام بإخطار البرنامج النصي window.parent الخاص به عند الانتهاء من التحميل وهو جاهز لاستدعائه مرة أخرى. بتمرير أحد الأشياء الخاصة به (على سبيل المثال ، وظيفة رد الاتصال) إلى البرنامج النصي الأصل ، يمكن لذلك الوالد الاتصال مباشرة مع البرنامج النصي في iframe دون الحاجة إلى القلق بشأن HTMLIFrameElement المرتبط به.


يمكن استدعاء وظيفة JS من iframe ، ولكن فقط عندما يكون كل من الأصل والصفحة التي تم تحميلها في iframe من نفس المجال مثل abc.com ، وكلاهما يستخدمان نفس البروتوكول أي أن كلاهما إما على http:// أو https:// .

ستفشل المكالمة في الحالات المذكورة أدناه:

  1. الصفحة الرئيسية وصفحة iframe من نطاق مختلف.
  2. انهم يستخدمون بروتوكولات مختلفة ، واحد على http: // وآخر على https: //.

أي حل بديل لهذا التقييد سيكون غير آمن للغاية.

على سبيل المثال ، تخيل أنني سجلت النطاق superwinningcontest.com وأرسلت روابط إلى رسائل البريد الإلكتروني للأشخاص. عندما حمّلوا الصفحة الرئيسية ، كان بإمكاني إخفاء بعض iframe على Facebook ، والتحقق من معاملات Amazon أو PayPal الأخيرة ، أو - إذا استخدموا خدمة لم تنفذ الأمان الكافي - قم بتحويل الأموال من حساباتهم. لهذا السبب تقتصر JavaScript على نفس المجال ونفس البروتوكول.


       $("#myframe").load(function() {
            alert("loaded");
        });




iframe