use*_*724 5 html javascript iframe
我正在动态创建 iframe 来显示通过 url 获取的文档。每个文档都位于 iframe 中,而 iframe 又位于 div 中。我有一个选项卡栏,允许显示任何文档,同时隐藏其余文档,这是一个典型的选项卡式页面。
我想显示包含接收第一个响应的 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
}
Run Code Online (Sandbox Code Playgroud)
下面,我描述了两种解决加载的第一个 iframe 的替代方法(A 和 B):
A) 当第一个 iframe 加载完毕后,停止加载其他 iframe。
您需要设置一种方法来跟踪正在添加的新 iframe,例如newIframes下面所示的数组。newIframes您可以通过在函数中运行以下逻辑之前跟踪或从 DOM 检索它们来完成此操作iframeLoaded()。
下面是一个示例,说明如何iframeLoaded()通过循环其他 iframe、停止加载它们并隐藏它们来修改函数:
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
}
});
}
Run Code Online (Sandbox Code Playgroud)
B)Promise.race()按照 joews 的建议使用。
Promise 可以使用 jQuery 创建,但 ES6 Harmony 包含对象Promise.race()的方法Promise。基本上,第一个完成的承诺是在承诺之间的竞争中解决的。
以下是如何修改代码以使用此 ES6 功能的示例:
1) 创建一个新函数createIframePromise(),为 iframe 创建承诺。
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;
}
Run Code Online (Sandbox Code Playgroud)
2) 在外部作用域中创建一个空数组来保存不同的 iframe Promise。
// hold the iframe promises.
var iframePromises = [];
Run Code Online (Sandbox Code Playgroud)
addTab()3)通过创建 iframe Promise 并将其推送到数组来修改您的函数iframePromises。
确保还newIframe.onload=iframeLoaded;从此函数中删除该行,因为我们将其移至createIframePromise()上面 #1 中新创建的函数中。
function addTab(fileName) {
// after "newIframe" with properties is created,
// create its promise and push it to the array.
iframePromises.push(createIframePromise(newIframe));
// ...
}
Run Code Online (Sandbox Code Playgroud)
4) 修改buildFileTabs()函数以在创建 iframe 并将其承诺存储在数组中后设置竞赛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.
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1954 次 |
| 最近记录: |