javascript - Holy grail for determining whether or not local iframe has loaded -


firstly, see question asked few times no answers seem satisfactory. looking able call script @ anytime , determine whether or not iframe has loaded - , not limit script require being added iframe tag in onload property.

here's background: have been working on unobtrusive script try , determine whether or not local iframes in dom have loaded, because 1 of our clients includes forms on website in iframes , many of them open in lightboxes - dynamically add iframes dom @ time. can attach open event of lightbox, hit or miss whether can "catch" iframe before has loaded.

let me explain little more.

in testing i've determined onload event fire once - , if bound before iframe loads. example: page should alert "added iframe tag" , listener attached afterward not fire - me makes sense. (i'm using iframe onload property simple example).

https://jsfiddle.net/g1bkd3u1/2/

<script>     function loaded () {         alert ("added iframe tag");         $("#test").load(function(){             alert("added after load finished");         });     }; </script> <iframe onload="loaded()" id="test" src="https://en.wikipedia.org/wiki/html_element#frames"></iframe> 

my next approach check document ready state of iframe seems work in of testing except chrome reports "complete" - expecting "access denied" cross domain request. i'm ok cross domain error because can disregard iframe since interested in local iframes - firefox reports "unintialized" i'm ok because know can attach onload event.

please open in chrome: https://jsfiddle.net/g1bkd3u1/

<iframe id="test" src="https://en.wikipedia.org/wiki/html_element#frames"></iframe> <script>     alert($("#test").contents()[0].readystate); </script> 

i've found if wait 100ms - iframe seems report expected (a cross domain security exception - want - don't want have wait arbitrary length).

https://jsfiddle.net/g1bkd3u1/4/

<iframe id="test" src="https://en.wikipedia.org/wiki/html_element#frames"></iframe> <script>     settimeout(function () {          try {             alert($("#test").contents()[0].readystate);         } catch (ignore) {             alert("cross domain request");         }     }, 100); </script> 

my current workaround / solution add onload event handler, detach iframe dom, insert dom in same place - onload event trigger. here's example waits 3 seconds (hoping thats enough time iframe load) show detaching , re-attaching causes iframe onload event fire.

https://jsfiddle.net/g1bkd3u1/5/

<iframe id="test" src="https://en.wikipedia.org/wiki/html_element#frames"></iframe> <script>     settimeout(function(){         var placeholder = $("<span>");         $("#test").load(function(){             alert("i know frame has loaded now");         }).after(placeholder).detach().insertafter(placeholder);         placeholder.detach();     }, 3000); </script> 

while works leaves me wondering if there better more elegant techniques checking iframe load (unobtrusively)?

thank time.

today ran bug removing , re-inserting of iframes breaking wysiwyg editor on website. created start of small jquery plugin check iframe readiness. not production ready , have not tested much, should provide nicer alternative detaching , re-attaching iframe - use polling if needs to, should remove setinterval when iframe ready.

it can used like:

$("iframe").iready(function() { ... }); 

https://jsfiddle.net/q0smjkh5/10/

<script>   (function($, document, undefined) {     $.fn["iready"] = function(callback) {       var ifr = this.filter("iframe"),           arg = arguments,           src = this,           clc = null, // collection           lng = 50,   // length of time wait between intervals           ivl = -1,   // interval id           chk = function(ifr) {             try {               var cnt = ifr.contents(),                   doc = cnt[0],                   src = ifr.attr("src"),                   url = doc.url;               switch (doc.readystate) {                 case "complete":                   if (!src || src === "about:blank") {                     // don't care empty iframes                     ifr.data("ready", "true");                   } else if (!url || url === "about:blank") {                     // empty document still needs loaded                     ifr.data("ready", undefined);                   } else {                     // not empty iframe , not empty src                     // should loaded                     ifr.data("ready", true);                   }                    break;                 case "interactive":                   ifr.data("ready", "true");                   break;                 case "loading":                 default:                   // still loading                   break;                  }             } catch (ignore) {               // far we're concerned iframe ready               // since won't able access cross domain               ifr.data("ready", "true");             }              return ifr.data("ready") === "true";           };        if (ifr.length) {         ifr.each(function() {           if (!$(this).data("ready")) {             // add collection             clc = (clc) ? clc.add($(this)) : $(this);           }         });         if (clc) {           ivl = setinterval(function() {             var rd = true;             clc.each(function() {               if (!$(this).data("ready")) {                 if (!chk($(this))) {                   rd = false;                 }               }             });              if (rd) {               clearinterval(ivl);               clc = null;               callback.apply(src, arg);             }           }, lng);         } else {           clc = null;           callback.apply(src, arg);         }       } else {         clc = null;         callback.apply(this, arguments);       }       return this;     };   }(jquery, document)); </script> 

the example waits until window has loaded dynamically add iframe dom, alerts document's readystate - in chrome displays "complete", incorrectly. iready function should called after , attempt output document's readystate proves cross domain exception - again has not been thoroughly tested works need.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -