I have several iframes how to detect the first one that loads

I am creating an iframe dynamically to display documents retrieved using the url. Each document is in an iframe, which in turn is in a div. I have a tab bar that allows me to display any document while hiding the rest of a typical tab.

I would like to display a div containing an iframe that gets the first response, i.e. displays the first one that loads and hides the rest. It is impossible to predict which one will load first, so I need a way to detect the first and display it and hide everything else.

I think I can do this if the onload iframe function checks the global boolean value, which is set to true when the first onload handler is executed.

I'm not sure why, but it seems error prone. Is there a better way to do this?

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
    }
+4
source share
1 answer

Below I describe two alternative methods (A and B), you can enable the loading of the first iframe:

A) Stop loading other iframes when loading the first iframe.

You will need to set up a way to track newly added frames, for example the array newIframesshown below. You can do this by tracking newIframesor retrieving them from the DOM before the iframeLoaded()following logic runs in your function .

The following is an example of how you can change your function iframeLoaded()by going through other frames, stop loading them and hide:

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) Promise.race(), joews.

Promises jQuery, ES6 Promise.race() Promise. , promises.

, 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 identifier.
            resolve(evt.target.getAttribute('div_id'));
        }
    });
    return iframePromise;
}

2) , iframe promises.

// hold the iframe promises.
var iframePromises = []; 

3) addTab(), iframe, 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));
    // ...
}

4) buildFileTabs(), iframes promises 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.
    });
}
+2

Source: https://habr.com/ru/post/1584521/


All Articles