我想显示包含接收第一个响应的iframe的div,即显示加载的第一个并隐藏其余的响应.没有办法预测哪个会首先加载所以我需要一种方法来检测第一个并显示它并隐藏所有其余的.
我想我可以通过让iframe onload函数检查一个全局布尔值来执行此操作,该布尔值在第一个onload处理程序运行时设置为true.
我不确定为什么,但这很容易出错.有一个更好的方法吗?
var firstDocumentReceived = false ; function buildFileTabs(evt) { firstDocumentReceived = false ; var files = evt.target.files; // files is a list of File objects. for (var i = 0,f; f = files[i]; i++) { addTab ( files[i].name ); } // create a div to display the requested document function addTab ( fileName ) { var newDiv = document.createElement("div"); newDiv.id = fileName.replace(".","_") + newRandomNumber() ; // create an iframe to place in the div var newIframe = document.createElement("iframe"); newIframe.onload=iframeLoaded ; newIframe.setAttribute("seamless",true ); newIframe.setAttribute("div_id",newDiv.id) ; newIframe.src = url ; // the iframe will contain a web page returned by the FDS server // nest the iframe in the div element newDiv.appendChild(newIframe) ; // nest the div element in the parent div document.getElementById("documentDisplay").appendChild(newDiv) ; ... function iframeLoaded ( event ) { if ( firstDocumentReceived === false ) { firstDocumentReceived = true ; // show the div associated with this event } else { // hide the div associated with this event }
解决方法
A)在加载第一个iframe时停止加载其他iframe.
您需要设置一种方法来跟踪正在添加的新iframe,例如下面显示的newIframes数组.您可以通过跟踪newIframes或在iframeLoaded()函数中运行以下逻辑之前从DOM中检索它们来执行此操作.
下面是一个示例,说明如何通过循环遍历其他iframe来修改iframeLoaded()函数,停止加载它们并隐藏它们:
function iframeLoaded(evt) { newIframes.forEach(function (newIframe) { if (newIframe.getAttribute('div_id') !== evt.target.getAttribute('div_id')) { // stop loading and hide the other iframes if (navigator.appName === 'Microsoft Internet Explorer') { newIframe.document.execCommand('Stop'); } else { newIframe.stop(); } newIframe.setAttribute('hidden','true'); // you can also delete it or set the css display to none } }); }
B)按照joews的建议使用Promise.race().
可以使用jQuery创建Promise,但ES6和声包括Promise
对象的Promise.race()
方法.基本上,完成的第一个承诺是在承诺之间的竞争中解决的.
以下是如何修改代码以使用此ES6功能的示例:
1)创建一个新函数createIframePromise(),为iframe创建一个promise.
function createIframePromise(newIframe) { var iframePromise = new Promise(function (resolve,reject) { newIframe.onload = function (evt) { // when the iframe finish loading,// resolve with the iframe's identifier. resolve(evt.target.getAttribute('div_id')); } }); return iframePromise; }
2)在外部作用域中创建一个空数组以保存不同的iframe promise.
// hold the iframe promises. var iframePromises = [];
3)通过创建iframe承诺然后将其推送到iframePromises数组来修改addTab()函数.
一定要删除行newIframe.onload = iframeLoaded;从这个函数,因为我们将它移动到上面#1中新创建的createIframePromise()函数.
function addTab(fileName) { // after "newIframe" with properties is created,// create its promise and push it to the array. iframePromises.push(createIframePromise(newIframe)); // ... }
4)修改buildFileTabs()函数以在创建iframe并将其promise存储在iframePromises数组中之后设置竞争.
function buildFileTabs(evt) { // ... Promise.race(iframePromises).then(function (firstIframeId) { // resolve... // put logic to show the first loaded iframe here. // (all other iframe promises lose the race) },function () { // reject... // nothing b/c "createIframePromise()" doesn't reject anything. }); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。