นี่เป็นปัญหาที่แน่นอนที่ฉันพบกับลูกค้าของเรา ฉันสร้าง jquery plugin เล็ก ๆ น้อย ๆ ที่ดูเหมือนว่าจะทำงานเพื่อความพร้อม iframe มันใช้การสำรวจความคิดเห็นเพื่อตรวจสอบเอกสาร iframe readyState รวมกับ url ของเอกสารภายในรวมกับแหล่ง iframe เพื่อให้แน่ใจว่า iframe เป็นจริง "พร้อม"
ปัญหาเกี่ยวกับ "onload" คือคุณต้องเข้าใช้ iframe จริงที่เพิ่มเข้ามาใน DOM หากคุณไม่ทำแล้วคุณต้องพยายามโหลด iframe ซึ่งถ้ามันถูกแคชคุณอาจไม่ได้ สิ่งที่ฉันต้องการคือสคริปต์ที่สามารถเรียกได้ทุกเวลาและตัดสินว่า iframe นั้น "พร้อม" หรือไม่
นี่คือคำถาม:
จอกศักดิ์สิทธิ์สำหรับการพิจารณาว่า iframe ในท้องที่นั้นโหลดแล้วหรือยัง
และนี่คือ jsfiddle ที่ฉันสร้างขึ้นมาในที่สุด
https://jsfiddle.net/q0smjkh5/10/
ใน jsfiddle ด้านบนฉันรอ onload เพื่อผนวก iframe ต่อ dom จากนั้นตรวจสอบสถานะพร้อมของเอกสารภายในของ iframe - ซึ่งควรจะข้ามโดเมนเพราะชี้ไปที่วิกิพีเดีย - แต่ Chrome ดูเหมือนจะรายงานว่า "สมบูรณ์" วิธีการที่ยุ่งยากของปลั๊กอินนั้นจะถูกเรียกใช้เมื่อ iframe พร้อมใช้งานจริง การเรียกกลับพยายามตรวจสอบสถานะพร้อมของเอกสารภายในอีกครั้งคราวนี้รายงานคำขอข้ามโดเมน (ซึ่งถูกต้อง) - อย่างไรก็ตามดูเหมือนว่าจะทำงานในสิ่งที่ฉันต้องการและหวังว่าจะช่วยคนอื่นได้
<script>
(function($, document, undefined) {
$.fn["iready"] = function(callback) {
var ifr = this.filter("iframe"),
arg = arguments,
src = this,
clc = null, // collection
lng = 50, // length of time to wait between intervals
ivl = -1, // interval id
chk = function(ifr) {
try {
var cnt = ifr.contents(),
doc = cnt[0],
src = ifr.attr("src"),
url = doc.URL;
switch (doc.readyState) {
case "complete":
if (!src || src === "about:blank") {
// we don't care about empty iframes
ifr.data("ready", "true");
} else if (!url || url === "about:blank") {
// empty document still needs loaded
ifr.data("ready", undefined);
} else {
// not an empty iframe and not an empty src
// should be loaded
ifr.data("ready", true);
}
break;
case "interactive":
ifr.data("ready", "true");
break;
case "loading":
default:
// still loading
break;
}
} catch (ignore) {
// as far as we're concerned the iframe is ready
// since we won't be able to access it cross domain
ifr.data("ready", "true");
}
return ifr.data("ready") === "true";
};
if (ifr.length) {
ifr.each(function() {
if (!$(this).data("ready")) {
// add to collection
clc = (clc) ? clc.add($(this)) : $(this);
}
});
if (clc) {
ivl = setInterval(function() {
var rd = true;
clc.each(function() {
if (!$(this).data("ready")) {
if (!chk($(this))) {
rd = false;
}
}
});
if (rd) {
clearInterval(ivl);
clc = null;
callback.apply(src, arg);
}
}, lng);
} else {
clc = null;
callback.apply(src, arg);
}
} else {
clc = null;
callback.apply(this, arguments);
}
return this;
};
}(jQuery, document));
</script>