جافاسكريبت - jQuery .ready داخل iframe مُدرج ديناميكياً
نحن نستخدم jQuery Thickbox لعرض إطار iframe بشكل ديناميكي عندما ينقر شخص ما على صورة. في هذا الإطار، نحن نستخدم Galleria وهي مكتبة جافا سكريبت لعرض صور متعددة.
يبدو أن المشكلة هي أن $ (document).ready في الإطار الفرعي (iframe) يتم تشغيله مبكرًا جدًا وأن محتوى الإطار الفرعي لم يتم تحميله بعد، لذا لا يتم تطبيق كود Galleria بشكل صحيح على عناصر DOM. يبدو أن $ (document).ready يستخدم حالة جاهزية الإطار الرئيسي لتحديد ما إذا كان الإطار الفرعي جاهزًا.
إذا قمنا باستخراج الدالة التي يتم استدعاؤها عند جاهزية المستند في دالة منفصلة واستدعائها بعد تأخير مقداره 100 مللي ثانية، فإنها تعمل، لكن لا يمكننا المخاطرة بذلك في بيئة الإنتاج مع كمبيوتر بطيء.
$(document).ready(function() { setTimeout(ApplyGalleria, 100); });
سؤالي: أي حدث من أحداث jQuery يجب علينا ربطه لنتمكن من تنفيذ الكود الخاص بنا عندما يكون الإطار المضمن الديناميكي جاهزًا وليس فقط والده؟
الإجابة رقم 1
لقد أجبت على سؤال مشابه (انظر Javascript callback when IFRAME is finished loading؟). يمكنك الحصول على التحكم في حدث تحميل iframe باستخدام الشيفرة التالية:
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function() {
callback(this);
});
}
في التعامل مع الإطارات المضمنة، وجدت أنه من الكافي استخدام حدث التحميل بدلاً من حدث جاهزية المستند.
الإجابة رقم 2
باستخدام jQuery 1.3.2، كان التالي يعمل بالنسبة لي:
$('iframe').ready(function() {
$('body', $('iframe').contents()).html('Hello World!');
});
مراجعة: في الواقع، الكود أعلاه أحيانًا يبدو أنه يعمل في فايرفوكس، ولا يبدو أبدًا أنه يعمل في أوبرا.
بدلاً من ذلك، قمت بتنفيذ حل قائم على الاستطلاع لأغراضي. وبشكل مبسط، يبدو كالتالي:
$(function() {
function manipIframe() {
el = $('body', $('iframe').contents());
if (el.length != 1) {
setTimeout(manipIframe, 100);
return;
}
el.html('Hello World!');
}
manipIframe();
});
هذا لا يتطلب كودًا في صفحات الإطار المستدعى (iframe). كل الكود موجود ويتم تنفيذه من الإطار/النافذة الأم.
الإجابة رقم 3
في IFrames عادةً أحل هذه المشكلة بوضع نص برمجي صغير في نهاية الكتلة:
<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
fireOnReadyEvent();
parent.IFrameLoaded();
//]]>
</script>
</body>
هذا العمل يعمل معي في معظم الأوقات. أحيانًا تكون أبسط الحلول وأكثرها سذاجة هي الأنسب.
