Đây là vấn đề chính xác tôi gặp phải với khách hàng của chúng tôi. Tôi đã tạo một plugin jquery nhỏ dường như hoạt động để sẵn sàng cho iframe. Nó sử dụng bỏ phiếu để kiểm tra tài liệu iframe readyState kết hợp với url tài liệu bên trong kết hợp với nguồn iframe để đảm bảo iframe thực sự "sẵn sàng".
Vấn đề với "onload" là bạn cần quyền truy cập vào iframe thực tế được thêm vào DOM, nếu bạn không cần phải thử tải iframe mà nếu nó được lưu vào bộ đệm thì bạn có thể không. Điều tôi cần là một tập lệnh có thể được gọi bất cứ lúc nào và xác định xem iframe có "sẵn sàng" hay không.
Đây là câu hỏi:
Chén thánh để xác định liệu iframe địa phương có được tải hay không
và đây là jsfiddle cuối cùng tôi đã nghĩ ra.
https://jsfiddle.net/q0smjkh5/10/
Trong jsfiddle ở trên, tôi đang chờ onload để nối iframe vào trạng thái dom, sau đó kiểm tra trạng thái sẵn sàng của tài liệu bên trong iframe - phải là tên miền chéo vì nó được trỏ đến wikipedia - nhưng Chrome dường như báo cáo "hoàn tất". Phương thức i sẵn của trình cắm sau đó được gọi khi iframe thực sự sẵn sàng. Cuộc gọi lại cố gắng kiểm tra lại trạng thái sẵn sàng của tài liệu bên trong - lần này báo cáo một yêu cầu tên miền chéo (chính xác) - dù sao thì nó dường như hoạt động cho những gì tôi cần và hy vọng nó sẽ giúp người khác.
<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>