Dan*_*idy 53 html javascript xulrunner frames firefox-addon
我可以使用load事件检测何时加载了iframe的内容.不幸的是,就我的目的而言,这有两个问题:
是否有某种方法可以确定是否发生上述任何一种错误?
我正在编写一个基于Mozilla/XULRunner的半网络半桌面应用程序,因此欢迎只在Mozilla中运行的解决方案.
spl*_*tne 14
如果您可以控制iframe页面(并且页面位于同一域名中),则策略可以如下所示:
var iFrameLoaded = false;true从iframe文档调用父项的函数(setIFrameLoaded();(例如).iFrameLoaded使用该timer对象检查该标志(将计时器设置为您的首选超时限制) - 如果该标志仍为false,则可以判断iframe未定期加载.我希望这有帮助.
我最近遇到了这个问题,不得不求助于在父页面上设置Javascript轮询操作(包含IFRAME标记).此JavaScript函数检查IFRAME的内容,以查找仅应存在于GOOD响应中的显式元素.当然,这假定您不必处理违反"同源政策"的问题.
而不是检查可能从许多不同的网络资源生成的所有可能的错误.我只是检查了一个我知道应该是一个良好响应的恒定正元素.
在预定的时间和/或尝试检测到预期元素的失败后,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");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
这是一个很晚的答案,但我会把它留给需要它的人。
任务: 加载 iframe 跨域内容,onLoaded在成功和onError加载错误时发出。
这是我可以开发的最跨浏览器来源的独立解决方案。但首先,我将简要介绍我采用的其他方法以及它们为什么不好。
1. iframe这对我来说有点震惊,iframe 只有onload事件,并且在加载和出错时调用它,无法知道它是否出错。
2. performance.getEntriesByType('resource')。此方法返回加载的资源。听起来像我们需要的。但是很遗憾,firefox 总是在资源数组中添加 Resource,无论加载还是失败。无法通过Resource实例知道它是否成功。照常。顺便说一下,这个方法在 ios<11 中不起作用。
3. 脚本我尝试使用<script>标签加载 html 。发射onload和onerror正确的,遗憾的是,仅适用于Chrome。
当我准备放弃时,我的老同事告诉我关于 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;
Run Code Online (Sandbox Code Playgroud)
在此之后,我们可以设置一些属性,<object>就像我们想要对iframe. 唯一的区别,我们应该使用<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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,困难的部分。像许多相同的元素一样,<object>没有回调规范,因此每个浏览器的行为都不同。
load事件。load和error正确。似乎与iframe, getEntriesByType, script....没有什么不同。但是,我们有原生浏览器回退!所以,因为我们直接设置了fallback(innerHtml),所以我们可以判断是否<object>加载了
function isReallyLoaded(obj) {
return obj.offsetHeight !== 5; // fallback height
}
Run Code Online (Sandbox Code Playgroud)
/**
* Chrome calls always, Firefox on load
*/
obj.onload = function() {
isReallyLoaded(obj) ? onLoaded() : onError();
};
/**
* Firefox on error
*/
obj.onerror = function() {
onError();
};
Run Code Online (Sandbox Code Playgroud)
但是如何处理 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;
}
Run Code Online (Sandbox Code Playgroud)
是的……没那么快。问题是,<object>当失败在规范行为中未提及时:
所以,代码需要一点点增强
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);
Run Code Online (Sandbox Code Playgroud)
好了,开始加载
document.body.appendChild(obj);
Run Code Online (Sandbox Code Playgroud)
这就是全部。我试图详细解释代码,所以它可能看起来不那么愚蠢。
PS WebDev 很烂
| 归档时间: |
|
| 查看次数: |
37059 次 |
| 最近记录: |