Саме з цим я стикався з нашим клієнтом. Я створив невеликий плагін jquery, який, здається, працює на готовність iframe. Він використовує опитування, щоб перевірити документ iframe readyState в поєднанні з внутрішнім URL-адресом документа в поєднанні з джерелом iframe, щоб переконатися, що iframe насправді "готовий".
Проблема "onload" полягає в тому, що вам потрібен доступ до фактичної рамки iframe, що додається до DOM, якщо ви цього не зробите, вам потрібно спробувати зафіксувати завантаження iframe, яке, якщо воно кешоване, то, можливо, ви не зробите. Мені потрібен був сценарій, який можна було б назвати в будь-який час, і визначити, чи був готовий iframe чи ні.
Ось питання:
Святий грааль для визначення завантаження місцевої рамки iframe чи ні
і ось jsfiddle, який я врешті-решт придумав.
https://jsfiddle.net/q0smjkh5/10/
У jsfiddle вище, я чекаю на завантаження, щоб додати iframe до дому, а потім перевіряю готовність внутрішнього документа iframe - який повинен бути міждоменним, оскільки він вказує на wikipedia - але Chrome, здається, повідомляє "завершеним". Потім метод виклику плагіну викликається, коли рамка дійсно готова. Зворотний виклик намагається перевірити стан готового внутрішнього документа ще раз - цього разу повідомляючи про запит між доменом (що правильно) - все одно, здається, він працює на те, що мені потрібно, і сподіваюся, що він допомагає іншим.
<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>