How can i run a function when the src of an iframe is changed? The iframe displays a site that is not on my server... When the user clicks on or presses a button inside the iframe, i'd like to perform a function to test whether the src has changed...
You have no access to the button inside the iframe if it's on a different domain so you can't use the "click" event. The only solution is to use the "load" event on the iframe:
<iframe src=".." onLoad="alert('new page loaded');"></iframe>
The load event will be triggered immediately when the page in the iframe has been loaded and then again when the other page (after changing the src) has been loaded. Then you can compare the first src (store it in a variable at the begin) with the current one and if they are different it means that the src has been changed.
Let's replace the onload function with ours. Don't forget to also call their onload function
function letswatch() {
var myIframe = document.getElementById("myIframe");
var oldonload = myIframe.onload;
if (typeof myIframe.onload != 'function') {
myIframe.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
Our function:
function func() {
alert("changed");
}
Please watch a working example at:
http://jsbin.com/uzucu4/2
I'm relatively sure you cannot see when that happens.
Related
I have a iFrame on my page thats display style is none. I have a javascript function to set the source and then set the display to block. The problem is that the iframe shows up before the content of it is loaded and thus I get a flickering effect. It goes white first and then displays the content. So I need to set the source, and when done loading all content of its source, only set its display style.
CSS & Javascript
.ShowMe{display:block;}
function(url)
{
document.getElementById('myIFrame').src = url;
document.getElementById('myIFrame').className = ShowMe;
}
It's simple as that:
<iframe onload="this.style.opacity=1;" style="opacity:0;border:none;
I would suggest you try the following:
<script type="javascript">
var iframe = document.createElement("myIFrame");
iframe.src = url;
if (navigator.userAgent.indexOf("MSIE") > -1 && !window.opera){
iframe.onreadystatechange = function(){
if (iframe.readyState == "complete"){
//not sure if your code works but it is below for reference
document.getElementById('myIFrame').class = ShowMe;
//or this which will work
//document.getElementById("myIFrame").className = "ShowMe";
}
};
}
else
{
iframe.onload = function(){
//not sure if your code works but it is below for reference
document.getElementById('myIFrame').class = ShowMe;
//or this which will work
//document.getElementById("myIFrame").className = "ShowMe";
};
}
</script>
Based on the code found here.
You could do this within the iframe:
window.onload = function () {
window.frameElement.className = 'ShowMe'; // 'ShowMe' or what ever you have in ShowMe variable.
}
Since you've tagged your question with [jquery], I assume you have executed the code within $(document).ready(). It is fired when the DOM is ready, i.e. it uses native DOMContentLoaded event (if available). window.onload is fired, when all resources on the page are ready.
The site I'm working on has a Live Chat plugin on an iframe. I'm trying to change an image if there are no agents available. My code works on the console, but nothing on the site.
var LiveChatStatus = $("iframe").contents().find(".agentStatus").html();
if (LiveChatStatus =="Offline"){
$('#liveChat').html('<img src="%%GLOBAL_ShopPath%%/product_images/theme_images/liveoffline.png">');
}
I tried this:
$('iframe').ready(function(){
var LiveChatStatus = $("iframe").contents().find(".agentStatus").html();
if (LiveChatStatus =="Offline"){
$('#liveChat').html('<img src="%%GLOBAL_ShopPath%%/product_images/theme_images/liveoffline.png">');
}
});
And this:
$(document).ready(function(){
var LiveChatStatus = $("iframe").contents().find(".agentStatus").html();
if (LiveChatStatus =="Offline"){
$('#liveChat').html('<img src="%%GLOBAL_ShopPath%%/product_images/theme_images/liveoffline.png">');
}
});
But neither worked
The best solution is to define a function in your parent such as function iframeLoaded(){...} and then in the iframe use:
$(function(){
parent.iframeLoaded();
})
this works cross-browser.
If you cannot change the code within the iframe, your best solution will be to attach the load event to the iframe..
$(function(){
$('iframe').on('load', function(){some code here...}); //attach the load event listener before adding the src of the iframe to prevent from the handler to miss the event..
$('iframe').attr('src','http://www.iframe-source.com/'); //add iframe src
});
Another way to bind to the load event of an iframe is to attach a load listener to the iframe before adding a src tag to the iframe.
Here's a simple example. This will also work with iframes that you don't control.
http://jsfiddle.net/V42ts/
// First add the listener.
$("#frame").load(function(){
alert("loaded!");
});
// Then add the src
$("#frame").attr({
src:"https://apple.com"
})
Found this from Elijah Manor's website which works very well
function iFrameLoaded(id, src) {
var deferred = $.Deferred(),
iframe = $("<iframe class='hiddenFrame'></iframe>").attr({
"id": id,
"src": src
});
iframe.load(deferred.resolve);
iframe.appendTo("body");
deferred.done(function() {
console.log("iframe loaded: " + id);
});
return deferred.promise();
}
$.when(iFrameLoaded("jQuery", "http://jquery.com"), iFrameLoaded("appendTo", "http://appendto.com")).then(function() {
console.log("Both iframes loaded");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
is it possible for me to make a jquery function run in an iframe using hash links?
perhaps something like this:
Parent code:
run function in iframe
<iframe src="pageName.html" name="iframe"></iframe>
Iframe code:
$(document).ready(function(){
$('body').the parent link is clicked, changing the url to pageName.html#runFunction (function(){
//blah blah blah//
});
});
thanks
Yes you can using the hashchange event. As long as you don't mind not supporting IE7 http://caniuse.com/hashchange
Alternatively, there is also a plugin that will backfill for you: http://benalman.com/projects/jquery-hashchange-plugin/
On the parent page simply change the URL of the iframe to a new hash.
$("iframe").prop("src", "http://google.com/#newhash");
Then in the docready of the iframe page:
$(window).bind("hashchange", function() {
alert(window.location.hash);
});
I am not sure exactly what you are trying here... but you can try this:
Where 'myIFrameFunction' is a function inside of 'pageName.html'...
Parent HTML:
click me for win
<iframe src="pageName.html"></iframe>
Iframe Javascript (as long as the function to be called is declared globally[direct in a script tag or js file]):
function testHash() {
var hash = window.location.hash.split('#')[1];
if ( typeof window[hash] != 'undefined' ) {
window[hash]();
}
}
var myTimer = setInterval(testHash, 100);
function myIFrameFunction() {
alert('It Works!');
}
I'm writing some code that will get executed before the DOM loads, basically, using Modernizr to get scripts. Now my issue is that I want to show a loading animation if the DOM loads and the scripts are still loading.
Modernizr is executed in the head. If I put the code to use document.getElementById in the head also, error is thrown because the DOM hasn't loaded. Now I have no idea how to solve this.
Here is the code I have so far:
<head>
<script>
var FileManager = {
IsLoading = false;
LoadRequiredFiles: function (config) {
config = config || {};
this.OnLoading = config.onLoadingCallback;
this.OnComplete = config.onCompleteCallback;
this.IsLoading = true;
if (this.OnLoading) {
this.OnLoading();
}
var self = this;
Modernizr.load([{
load: '/jquery.min.js',
complete: function () {
if (self.OnComplete) {
self.OnComplete();
}
self.IsLoading = true;
}
},
]);
}
};
var globalLoadingId = 'globalLoader';
FileManager.LoadRequiredFiles({
onLoadingCallback: function () {
document.getElementById(globalLoadingId).style.display = 'block';
},
onCompleteCallback: function () {
document.getElementById(globalLoadingId).style.display = 'none';
}
});
</script>
I used to execute this code below the <body> tag, and it worked. Now I moved it into the <head>. So I used to pass 2 callbacks to it. Now I'd rather attach events to it and handle them in the body (assuming thats where the DOM is loaded).
What I'd like to do:
<head>
<script>
FileManager.LoadRequiredFiles();
</script>
</head>
<body>
<script>
//Bind the event, not sure if this is even possible in javascript.
FileManager.OnCompleted += fileManagerCompleted;
fileManagerCompleted()
{
document.getElementById(globalLoadingId).style.display = 'none';
}
if(FileManager.IsLoading)
{
document.getElementById(globalLoadingId).style.display = 'block';
}
</script>
</body>
The page is your canvas for display. You can't show anything before it loads. It sounds more like you want a very small page to load (quickly) where you could display your progress and then your code could dynamically load/display the rest of the page with ajax calls and javascript showing progress as it goes. That's the only way to get out in front of the rest of the page load that I know of.
The only entirely reliable way to run a script that manipulates the DOM is to use the body onload event. (window.onload is popular, but not quite 100% reliable.)
There are some browsers that implement a onDocumentReady event that can be kind-of-sort-of faked in IE, but I don't recommend its use.
Using getElementById will not, by itself, throw an error if used in the head. You might be causing an error because you aren't checking the returned value, which will be null if an element with the specified id wasn't found, e.g.
var el = document.getElementById('foo');
if (el) {
// do somethig with el
} else {
// el wasn't found
}
Your problem is how to display the image only if the scripts are still loading and the page is visible. The simple answer is don't use client-side script loading, do it at the server. :-)
If you want to persist with script loading, add a class to the loading image, say "hideOnLoad". Have a callback from the last script load that sets the rule to "display: none" (just create and add style sheet with that one rule using script).
Now you just include the loading image as the first element in the body with a class of "hideOnLoad", knowing that when scripts have finished loading they will hide the image regardless of whether it (or any other element with the same class) existed at the time or not.
I can't figure out what I'm doing wrong here.
I am building a website with no server-side
I have a main page with an iframe and on a button click I want the iframe's src to change and a function in it to be invoked with a passed parameter.
The function is not called for some reason.
here's my code:
the iframe:
<iframe id="main_area_frame" name="main_area_frame" src="" frameborder="0" width="100%" height="100%"></iframe>
the onclick function:
function onSubMenuClick(images)
{
//Set Images Frame
main_area = document.getElementById("main_area_frame");
main_area.src = "ImagesFrame.html";
main_area.contentWindow.initializeImages(images);
}
the function in the iframe(ImagesFrame.html):
function initializeImages(imagesStr)
{
alert("initializeImages");
...
}
some weird things I noticed are that
when adding an alert just before main_area.contentWindow.initializeImages(images);
the function is somehow called successfully.
if I set the iframe's src from the begining and skip the line main_area.src = "ImagesFrame.html"; - the function is again, called.
any ideas?
Not sure if that is the cause, but I would try putting a delay(sleep) between
main_area.src = "ImagesFrame.html";
and
main_area.contentWindow.initializeImages(images);
in order to allow the iframe to be rendered (I do not know if it is the rendered by the same frame or the browser launches a new one).
Just my two cents.
I have had success with publishing the function from the child iframe during
onload handling. For example, (substituting your funcName):
In child iframe, edit body tag (or use equivalent javascript)
<body onload='top.funcName = funcName'>
In parent page, edit javascript; now the
funcName will be generally accessible as,
value = top.funcName( )