Lets say I have the following:
default.asp:
<iframe src="frameOne.asp" id="myframeOne"></iframe>
frameOne.asp:
<iframe src="frameTwo.asp" id="myframe"></iframe>
frameTwo.asp:
<div id="hello">Test text</div>
Why does the following doesn't work (#1):
$("#myframeOne").load(function () {
$('#myframeOne').contents().find('#myframeTwo').load(function(){
$('#myframeOne').contents().find('#myframeTwo').contents().find('#hello').css('background-color','blue');
});
});
And this does apply the CSS?(#2):
$("#myframeOne").load(function () {
$('#myframeOne').contents().find('#myframeTwo').ready(function(){
$('#myframeOne').contents().find('#myframeTwo').contents().find('#hello').css('background-color','blue');
});
});
And this one doesn't(#3):
$("#myframeOne").ready(function () {
$('#myframeOne').contents().find('#myframeTwo').ready(function(){
$('#myframeOne').contents().find('#myframeTwo').contents().find('#hello').css('background-color','blue');
});
});
As I understand the .load waits until the content of the iframe is loaded, so I don't quite understand why it behaves differently on the frames (why it works when apply on the outer frame, but not in the inner frame).
With iframes I work always with the load function. I've got problems with the ready function too so try to work with the load function.
Related
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!");
});
I am trying to implement JavaScript within an iframe from the parent page. I read Invoking JavaScript code in an iframe from the parent page, however, get the following error.
Error: Permission denied to access property "showIt"
document.getElementById('targetFrame').contentWindow.showIt();
I've tried implementing this both on jsfiddle as well as my server (don't know if it matters, but it uses https), but get the same results. I've also tried removing the $(function(){}) wrapper on the child iframe, but no change.
My actual application is described below.
How can this be accomplished?
My Application:
I have my parent page https://jsfiddle.net/5f4ct5ph/6/) which contains an iframe.
<iframe width="100%" height="300" src="https://jsfiddle.net/5f4ct5ph/5/embedded/result/" id="targetFrame"></iframe>
<button id="show">Show</button>
<button id="hide">Hide</button>
$(function () {
$('#show').click(function () {
document.getElementById('targetFrame').contentWindow.showIt();
});
$('#hide').click(function () {
document.getElementById('targetFrame').contentWindow.hideIt();
});
});
The iframe page (https://jsfiddle.net/5f4ct5ph/5/) contains a tinymce editor.
<div id="content">Initial content goes here</div>
#content {height:200px;width:400px;border: 1px solid;}
$(function () {
tinymce.init({
selector: "#content",
width : 400,
height: 200,
setup : function(ed) {
ed.on('init', function(e) {
e.target.hide();
});
}
});
function showIt() {
tinymce.get('content').show();
};
function hideIt() {
tinymce.get('content').hide();
};
});
fiddle.jshell.net (the parent document domain) is different to jsfiddle.net (your iframe domain).
I've changed your code to point to the jshell.net url instead (You can get this by using the URL of the frame in the bottom right of jsfiddle rather than the address bar).
https://jsfiddle.net/GarryPas/5f4ct5ph/7/
showIt() and hideIt() don't seem to be defined (because they are inside an anonymous function). Change this:
$(function () {
...
function showIt() {
tinymce.get('content').show();
};
function hideIt() {
tinymce.get('content').hide();
};
});
To this:
$(function () {
...
});
function showIt() {
tinymce.get('content').show();
}
function hideIt() {
tinymce.get('content').hide();
}
Then remove my alerts and put back your original code which I commented out.
Normally, if iframe and parent are on same domain, it should work, but there are restriction to communication from window to window. You can try using postMessage, like this:
In your parent page, in the click event, instead of calling the function directly, you could do this:
child_window = document.getElementById('targetFrame').contentWindow;
child_window.postMessage("showit" or "hideit", your_domain);
The in you iframe:
window.addEventListener("message", check_message, false);
function check_message(event){
switch(event.data){
case "showit":
showIt();
break;
case "hideit":
hideIt();
break;
default:
breaks;
}
Make sure your functions showIt and hideIt are available from where you call check_message.
Again, there may be another problem, it's hard to tell with the embedded jsfiddle, but in any case, when dealing with iframes and javascript, postMessage is often more flexible and secure than accessing functions and variables directly.
I want to check if iframe is loaded with the following code:
$(document).ready(function() {
jQuery('#iframeID').ready(somefunction);
}
It seems that 'somefunction' is called before iframe is loaded (the iframe is empty - just empty html-head-body).
Any idea why this happens?
Thank you.
Try this instead.
$('#iframeID').load(function() {
callback(this);
});
While dealing with iFrames, it is good enough to use load() event instead of $(document).ready() event.
This is because you're checking if the iFrame is ready, not the document inside.
$(document.getElementById('myframe').contentWindow.document).ready(someFunction);
should do the trick.
I have tried:
$("#frameName").ready(function() {
// Write you frame on load javascript code here
} );
and it did not work for me.
this did:
$("#frameName").load( function() {
//code goes here
} );
Even though the event does not fire as quickly - it waits until images and css have loaded also.
i have a script that cuts a part of the iframe( iframe without headers ) and shows it. my problem is if i make actions within this iframe, the iframe reloads but is not applying the jquery filtering to give me only that part but instad gives me all the page with headers so i'm assuming that script is not working when it reload the iframe without the window reload of the main page that has the iframe:
<iframe class="test" width="100%" height="100%" src="/message.html?msjId=260" style="height:100%;width:100%;">
$(window).load(function () {
$('.test').each(function(){
var filteredContents1 = $(this).contents().find('.div_iframe').html();
$(this).contents().find('body').html(filteredContents1);
});
});
any solutions please ?
I think you need to add load events for frames as well. Add the load event in document.ready function as given below. If it works you may be able to omit window load event you already have for filtering frames data.
$(document).ready(function(){
$('.test').load(function () {
var filteredContents1 = $('#frame1').contents().find('#divChild').html();
$('#frame1').contents().find('body').html(filteredContents1);
});
});
Update on request of questioner
$(document).ready(function(){
$('.test').load(function () {
$('#frame1, #frame2, #frame3').each(function(){
var filteredContents1 = $(this).contents().find('#divChild').html();
$(this).contents().find('body').html(filteredContents1);
});
});
});
.
Does anyone know if there is such a thing?
I have a iframe that's being inserted with $.ajax() and I want to do some stuff after the contents from the iframe are completely loaded:
....
success: function(html){ // <-- html is the IFRAME (#theiframe)
$(this).html(html); // $(this) is the container element
$(this).show();
$('#theiframe').load(function(){
alert('loaded!');
}
....
it works, but I see the IFRAME is loaded twice (the alert also shows twice).
use iframe onload event
$('#theiframe').on("load", function() {
alert(1);
});
If possible, you'd be better off handling the load event within the iframe's document and calling out to a function in the containing document. This has the advantage of working in all browsers and only running once.
In the main document:
function iframeLoaded() {
alert("Iframe loaded!");
}
In the iframe document:
window.onload = function() {
parent.iframeLoaded();
}
Along the lines of Tim Down's answer but leveraging jQuery (mentioned by the OP) and loosely coupling the containing page and the iframe, you could do the following:
In the iframe:
<script>
$(function() {
var w = window;
if (w.frameElement != null
&& w.frameElement.nodeName === "IFRAME"
&& w.parent.jQuery) {
w.parent.jQuery(w.parent.document).trigger('iframeready');
}
});
</script>
In the containing page:
<script>
function myHandler() {
alert('iframe (almost) loaded');
}
$(document).on('iframeready', myHandler);
</script>
The iframe fires an event on the (potentially existing) parent window's document - please beware that the parent document needs a jQuery instance of itself for this to work. Then, in the parent window you attach a handler to react to that event.
This solution has the advantage of not breaking when the containing page does not contain the expected load handler. More generally speaking, it shouldn't be the concern of the iframe to know its surrounding environment.
Please note, that we're leveraging the DOM ready event to fire the event - which should be suitable for most use cases. If it's not, simply attach the event trigger line to the window's load event like so:
$(window).on('load', function() { ... });
That's the same behavior I've seen: iframe's load() will fire first on an empty iframe, then the second time when your page is loaded.
Edit: Hmm, interesting. You could increment a counter in your event handler, and a) ignore the first load event, or b) ignore any duplicate load event.
Without code in iframe + animate:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
function resizeIframe(obj) {
jQuery(document).ready(function($) {
$(obj).animate({height: obj.contentWindow.document.body.scrollHeight + 'px'}, 500)
});
}
</script>
<iframe width="100%" src="iframe.html" height="0" frameborder="0" scrolling="no" onload="resizeIframe(this)" >
You may use the jquery's Contents method to get the content of the iframe.
If you want it to be more generic and independent, you can use cookie. Iframe content can set a cookie. With jquery.cookie and a timer (or in this case javascript timer), you can check if the cookie is set each second or so.
//token should be a unique random value which is also sent to ifame to get set
iframeLoadCheckTimer = window.setInterval(function () {
cookieValue = $.cookie('iframeToken');
if (cookieValue == token)
{
window.clearInterval(iframeLoadCheckTimer );
$.cookie('iframeToken', null, {
expires: 1,
path: '/'
});
}
}, 1000);