Checking if iframe is ready to be written to - javascript

A 3rd party script on my web page creates an iframe. I need to know when this iframe is ready, so I can manipulate its DOM.
I can think of a hacky approach: repeatedly try to modify the iFrame's DOM, and return success when a change we make sticks between two attempts. For this to work, I would prefer a property I can check on the iframe repeatedly.
Is there an alternative, cross-browser evented approach to knowing that the iframe is ready? E.g. can we redefine the onLoad function to call into our code (but I don't know if I can do this, since I didn't create the iframe).

using jquery?
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function()
{
callback(this);
});
}
Question answered in jQuery .ready in a dynamically inserted iframe

Have a variable in the parent:
var setToLoad = false;
Follow it up with a function to set it:
function SetToLoad() {
setToLoad = true;
}
Then in the child iframe call this function using the window.opener
function CallSetToLoad() {
window.opener.SetToLoad();
}
window.onload = CallSetToLoad;
This won't run until the iframe is finished loading, and if it's in the same domain it'll allow access to the opener. This would require editing a small portion of the 3rd party script.
EDIT: Alternative solution
Given that you can't edit the script, you might try something like:
frames["myiframe"].onload = function()
{
// do your stuff here
}

Can you inject arbitrary scripting code into your iframe? If so, you should be able to make it so that some code executes in the iframe upon the the iframe loading that calls code in the parent page.

First: You probably won't be able to manipulate its dom when it loads html from other domain
And You probably are interested in DOMready.
Look here:
jQuery .ready in a dynamically inserted iframe

Bilal,
There's a document.readyState property that you can check (works in IE).
foo(){
if([your iframe id].document.readyState != "complete")
{
setTimeout("foo()", 500); //wait 500 ms then call foo
}
else
{
//iframe doc is ready
}
}
Arkady

Related

How to wait to execute JS until readyState == Complete for document and window? [duplicate]

I need to execute some JavaScript code when the page has fully loaded. This includes things like images.
I know you can check if the DOM is ready, but I don’t know if this is the same as when the page is fully loaded.
That's called load. It came waaaaay before DOM ready was around, and DOM ready was actually created for the exact reason that load waited on images.
window.addEventListener('load', function () {
alert("It's loaded!")
})
For completeness sake, you might also want to bind it to DOMContentLoaded, which is now widely supported
document.addEventListener("DOMContentLoaded", function(event){
// your code here
});
More info: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Usually you can use window.onload, but you may notice that recent browsers don't fire window.onload when you use the back/forward history buttons.
Some people suggest weird contortions to work around this problem, but really if you just make a window.onunload handler (even one that doesn't do anything), this caching behavior will be disabled in all browsers. The MDN documents this "feature" pretty well, but for some reason there are still people using setInterval and other weird hacks.
Some versions of Opera have a bug that can be worked around by adding the following somewhere in your page:
<script>history.navigationMode = 'compatible';</script>
If you're just trying to get a javascript function called once per-view (and not necessarily after the DOM is finished loading), you can do something like this:
<img src="javascript:location.href='javascript:yourFunction();';">
For example, I use this trick to preload a very large file into the cache on a loading screen:
<img src="bigfile"
onload="this.location.href='javascript:location.href=\'javascript:doredir();\';';doredir();">
Try this it Only Run After Entire Page Has Loaded
By Javascript
window.onload = function(){
// code goes here
};
By Jquery
$(window).bind("load", function() {
// code goes here
});
Try this code
document.onreadystatechange = function () {
if (document.readyState == "complete") {
initApplication();
}
}
visit https://developer.mozilla.org/en-US/docs/DOM/document.readyState for more details
Javascript using the onLoad() event, will wait for the page to be loaded before executing.
<body onload="somecode();" >
If you're using the jQuery framework's document ready function the code will load as soon as the DOM is loaded and before the page contents are loaded:
$(document).ready(function() {
// jQuery code goes here
});
the window.onload event will fire when everything is loaded, including images etc.
You would want to check the DOM ready status if you wanted your js code to execute as early as possible, but you still need to access DOM elements.
You may want to use window.onload, as the docs indicate that it's not fired until both the DOM is ready and ALL of the other assets in the page (images, etc.) are loaded.
In modern browsers with modern javascript (>= 2015) you can add type="module" to your script tag, and everything inside that script will execute after whole page loads. e.g:
<script type="module">
alert("runs after") // Whole page loads before this line execute
</script>
<script>
alert("runs before")
</script>
also older browsers will understand nomodule attribute. Something like this:
<script nomodule>
alert("tuns after")
</script>
For more information you can visit javascript.info.
And here's a way to do it with PrototypeJS:
Event.observe(window, 'load', function(event) {
// Do stuff
});
The onload property of the GlobalEventHandlers mixin is an event
handler for the load event of a Window, XMLHttpRequest, element,
etc., which fires when the resource has loaded.
So basically javascript already has onload method on window which get executed which page fully loaded including images...
You can do something:
var spinner = true;
window.onload = function() {
//whatever you like to do now, for example hide the spinner in this case
spinner = false;
};
Completing the answers from #Matchu and #abSiddique.
This:
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
});
Is the same as this but using the onload event handler property:
window.onload = (event) => {
console.log('page is fully loaded');
};
Source:
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Live example here:
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event#live_example
If you need to use many onload use $(window).load instead (jQuery):
$(window).load(function() {
//code
});
2019 update: This is was the answer that worked for me. As I needed multiple ajax requests to fire and return data first to count the list items.
$(document).ajaxComplete(function(){
alert("Everything is ready now!");
});

Javascript Deferred Functions

I've been looking around at JavaScript to try and get some code to load asynchronously
I found this code sample
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener("load", downloadJSAtOnload, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", downloadJSAtOnload);
}
else {
window.onload = downloadJSAtOnload;
}
</script>
from http://www.feedthebot.com/pagespeed/defer-loading-javascript.html
The thing is it doesn't quite do what I'm trying to achieve. I would like to be able to do something similar but setup a deferred or some type of function that is called after this has all loaded. Is that possible? If so can anyone help explain how?
You can try to use the onload event of the script tags you are loading. See this question, for example: Trying to fire the onload event on script tag. However, this mechanism seems pretty sketchy and may not be cross-browser.
Another possible approach is to have the script that is being loaded trigger an event that can be handled by the existing javascript on the page. This may or may not make sense for your particular case, and it requires you to have control over the loaded script.
Finally, these days it's rare for javascript loading to be a performance bottleneck for your website. So why are you trying to dynamically load javascript? Could you solve the same problem by loading some other resource, e.g. by doing an AJAX request?
You've tagged jQuery on your question. It has $.getScript() which does exactly what you're asking for in a purely cross browser fashion. It will load the script asynchronously and then call the specified callback when the script has finished loading and initializing:
$.getScript("defer.js", function() {
// script loaded here
// you can run code here that uses that script
});
If you really want to wait until the DOM is loaded before loading this script (generally not necessary), you could do this:
$(document).ready(function() {
$.getScript("defer.js", function() {
// script loaded here
// you can run code here that uses that script
});
});
Or, to wait until ALL other resources are loaded including images:
$(window).load(function() {
$.getScript("defer.js", function() {
// script loaded here
// you can run code here that uses that script
});
});
If you're interested in some references on when scripts are loaded (particularly with defer and async attributes, you can read this detailed post.

Call function anytime a link is moused over on an arbitrary page?

I apologize for the possibly naive nature of this question but I am not a web developer by day.
Is it possible to write a script such that, for any arbitrary web page, a function that I have written will be called if a URL is moused over? I was initially thinking that I could use document.links to assemble an array of all of the hrefs in a document and add an onmouseover event attribute to each of them but, unless I'm mistaken, that would overwrite any existing onmouseover attributes already present in the page. Not ideal.
I'm not sure if by arbitrary web page you mean any pages on any domains or any pages of your own domain, but for the latter you could put something like the following in your pages:
$(function () {
$(document).on('mouseenter', 'a', function () {
console.log(this, 'hovered');
});
});
If you mean any page your browse to on the net, then you will have to write a browser extension for the browser your are using. For Chrome have a look at this.
You could try getting everything with the a tag and inject an onmouseover.
window.onload = function(){
for(m=0;m<document.getElementsByTagName('a');m++){
if(document.getElementsByTagName('a')[m].className == 'someclass'){
document.getElementsByTagName('a')[m].onmouseover = function(){
Your Code
}
}
}
}

Check if a parent iFrame has jQuery already loaded

I'm trying to create a login widget in an iframe that can be used on a clients website. This iframe will be using jQuery, but I first wont to be able to check if the parent document has jQuery loaded, if not, load it.
I've tried several different techniques but none seem to wont to work, or decide to load the jQuery library twice.
Any help would be greatly appreciated.
This code block is within the page loaded inside the iframe, which refuses to co-operate.
<script>
var jQOutput = false;
function initjQuery() {
if (typeof(jQuery) == 'undefined'){
if (!jQOutput){
jQOutput = true;
var jScript = document.createElement('script');
jScript.setAttribute("type", "text/javascript");
jScript.setAttribute("src", "js/libs/jquery/jquery-min.js");
}
setTimeout("initjQuery()", 50);
} else {
$(function() {
$("#email").css({"background":"red"});
//visual aid to see if jQuery is loaded.
});
}
}
</script>
I just want to check and see if the parent to the iframe has loaded jQuery, and if not, load it myself, as I'll be using it to perform several tasks needed to complete the login proceedure.
Entented comment:
I dont think what you want to archive is posible because of same origin policy (Cross domain access via JavaScript) - look it op on Google... http://google.com/search?q=same+origin+policy
If you on the other hand dont violate the same origin policy you can archive what you want using something like this:
var parent = window.parent; // This refers to parent's window object
if ( parent && parent.jQuery ) { // Check to see if parent and parent.jQuery is truly
window.jQuery = parent.jQuery;
window.$ = parent.jQuery;
}
else {
// load jQuery here
}
The JavaScript code of your widget has to be divided into two parts. One of them would be loaded on a client's site. It would have permissions to access the DOM of the site: load jQuery if needed, create an iframe, etc. (Be especially careful with global variables there! Try not to use them at all since they can conflict with the code of the site.) Note that this part wouldn't have access to the DOM of the iframe. That's why you need the second part, which would be loaded inside of the iframe. You can use cross-domain techniques for the parts to exchange messages with each other. I'd advise you to check out the easyXDM library.

Iframe loaded in javascript

I dynamically am changing the location and src of an iframe.
Is there an event that will tell me when the page i just put has loaded from javascript?
Basically I want to append something to the page but first need to know that everything is loaded.
You may want to use the onLoad event, as in the following example:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
The alert will pop-up whenever the location within the iframe changes, including the first time it finishes loading. However note that this may not work with some older browsers like IE5 and early Opera. (Source)
Something like this:
frame.src = url;
if (frame.addEventListener) {
frame.addEventListener("load", function () {
*insert code here*
}, false);
} else if (frame.attachEvent) {
frame.attachEvent("load", function () {
*insert code here*
}
}
Note that this code is not tested, and may not work.
BTW, onload, onclick, and such are outdated, mainly because they can only handle one event listener, unless you build your own (bad for productivity).

Categories