我可以使用load事件检测iframe的内容何时加载。不幸的是,就我的目的而言,这有两个问题:
有没有什么方法可以可靠地确定上面的错误是否发生了?
我正在编写一个基于Mozilla/XULRunner的半web半桌面应用程序,因此欢迎只在Mozilla中工作的解决方案。
发布于 2008-12-17 19:38:50
如果您可以控制iframe页面(并且这些页面位于相同的域名上),则可以采用以下策略:
在父文档中,初始化加载iframe文档的变量,将父文档中的此变量设置为使用timer
对象从iframe文档调用父函数true
(setIFrameLoaded();
var iFrameLoaded = false;
iFrameLoaded
标志(将计时器设置为您首选的超时限制)-如果该标志仍然为false,则可以断定未定期加载iframe。我希望这能帮到你。
发布于 2008-12-22 16:29:24
我最近遇到了这个问题,不得不在父页面(包含IFRAME标签)上设置一个Javascript轮询操作。此JavaScript函数检查IFRAME的内容,查找应该只存在于良好响应中的显式元素。当然,这假设您不必处理违反“同源策略”的问题。
而不是检查可能从许多不同的网络资源产生的所有可能的错误。我只是简单地检查了一个常量的积极因素,我知道应该是一个良好的反应。
在预先确定的时间和/或尝试检测预期元素的失败次数之后,JavaScript修改IFRAME的SRC属性(从我的Servlet请求一个用户友好的错误页面),而不是显示典型的HTTP错误消息。JavaScript还可以很容易地修改SRC属性以发出完全不同的请求。
function checkForContents(){
var contents=document.getElementById('myiframe').contentWindow.document
if(contents){
alert('found contents of myiframe:' + contents);
if(contents.documentElement){
if(contents.documentElement.innerHTML){
alert("Found contents: " +contents.documentElement.innerHTML);
if(contents.documentElement.innerHTML.indexOf("FIND_ME") > -1){
openMediumWindow("woot.html", "mypopup");
}
}
}
}
}
发布于 2019-03-02 06:09:54
这是一个非常晚的答案,但我会把它留给需要它的人。
任务:加载iframe跨域内容,成功时发出onLoaded
,加载错误时发出onError
。
这是我能开发的最具跨浏览器来源独立的解决方案。但首先,我将简要介绍一下我曾经使用过的其他方法,以及它们为什么不好。
iframe这对我来说有点震惊,那个iframe只有onload
事件,它在加载和错误时被调用,没有办法知道它是不是错误。
performance.getEntriesByType('resource'). 2.此方法返回加载的资源。听起来就是我们需要的。但遗憾的是,firefox总是在资源数组中添加资源,无论它是加载还是失败。没有办法通过Resource
实例知道它是否成功。像往常一样。顺便说一句,这种方法在ios<11中不起作用。
3.script我尝试使用<script>
标签加载。遗憾的是,只有在Chrome中才能正确地发射onload
和onerror
。
当我准备放弃的时候,我的学长告诉我关于html4 tag <object>
的事情。它类似于<iframe>
标签,除了在内容未加载时有回退。这听起来就是我们需要的!遗憾的是,这并不像听起来那么容易。
代码段
var obj = document.createElement('object');
// we need to specify a callback (i will mention why later)
obj.innerHTML = '<div style="height:5px"><div/>'; // fallback
obj.style.display = 'block'; // so height=5px will work
obj.style.visibility = 'hidden'; // to hide before loaded
obj.data = src;
在此之后,我们可以像对iframe
一样设置一些属性给<object>
。唯一的区别是,我们应该使用<params>
,而不是属性,但它们的名称和值是相同的。
for (var prop in params) {
if (params.hasOwnProperty(prop)) {
var param = document.createElement('param');
param.name = prop;
param.value = params[prop];
obj.appendChild(param);
}
}
现在,最难的部分。与许多类似的元素一样,<object>
没有回调规范,因此每个浏览器的行为都不同。
load
event.load
和error
correctly.看起来和iframe
,getEntriesByType
,script
没有什么不同。但是,我们有本机浏览器回退!因此,因为我们直接设置了回退(innerHtml),所以我们可以判断是否加载了<object>
function isReallyLoaded(obj) {
return obj.offsetHeight !== 5; // fallback height
}
/**
* Chrome calls always, Firefox on load
*/
obj.onload = function() {
isReallyLoaded(obj) ? onLoaded() : onError();
};
/**
* Firefox on error
*/
obj.onerror = function() {
onError();
};
但是如何处理Safari呢?很好的老setTimeout
。
var interval = function() {
if (isLoaded) { // some flag
return;
}
if (hasResult(obj)) {
if (isReallyLoaded(obj)) {
onLoaded();
} else {
onError();
}
}
setTimeout(interval, 100);
};
function hasResult(obj) {
return obj.offsetHeight > 0;
}
是啊……还没那么快。问题是,<object>
在失败时有规范中没有提到的行为:
尝试加载(size=0)
的大小
因此,代码需要一些增强。
var interval = function() {
if (isLoaded) { // some flag
return;
}
if (hasResult(obj)) {
if (isReallyLoaded(obj)) {
interval.count++;
// needs less then 400ms to fallback
interval.count > 4 && onLoadedResult(obj, onLoaded);
} else {
onErrorResult(obj, onError);
}
}
setTimeout(interval, 100);
};
interval.count = 0;
setTimeout(interval, 100);
好的,然后开始加载
document.body.appendChild(obj);
,这都是。我试图解释代码的每一个细节,这样看起来就不那么愚蠢了。
P.S. WebDev烂透了
https://stackoverflow.com/questions/375710
复制相似问题