Making script wait until iframe has loaded before running - javascript

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>

Related

Place 15 seconds delay in a jQuery script

I have a script that closes an iframe after a click it.
I need that when you click on the link inside the iframe has delay 15 seconds to load a page within the iframe and after 15 seconds the iframe automatically closes.
$(window).on('blur',function(e) {
if($(this).data('mouseIn') != 'yes')return;
$('iframe').filter(function(){
return $(this).data('mouseIn') == 'yes';
}).trigger('iframeclick');
});
$(window).mouseenter(function(){
$(this).data('mouseIn', 'yes');
}).mouseleave(function(){
$(this).data('mouseIn', 'no');
});
$('iframe').mouseenter(function(){
$(this).data('mouseIn', 'yes');
$(window).data('mouseIn', 'yes');
}).mouseleave(function(){
$(this).data('mouseIn', null);
});
$('iframe').on('iframeclick', function(){
$(this).hide()
});
$('<input type="text" style="position:absolute;opacity:0;height:0px;width:0px;"/>').appendTo(document.body).blur(function(){
$(window).trigger('blur');
}).focus();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<iframe style="width:400px;
height:250px;" src="//example.com"></iframe>
If you want to stick to Jquery you can use .delay()
http://api.jquery.com/delay/
To wait 15 seconds before the iframe close, you should do this :
$('iframe').on('iframeclick', function(){
$(this).delay(15000).hide();
}
In a simple way, you put a delay of 15s before the "hide" action
You are looking for the setTimeout() method. You can find how to use it here: http://www.w3schools.com/jsref/met_win_settimeout.asp.
In your case would be something like (this can be optimized, take out global var etc.):
globalVar = null;
function closeIframe() {
globalVar.hide();
}
$('iframe').on('iframeclick', function(){
globalVar = $(this);
setTimeout("closeIframe()", 15000);
});
Use good old setTimeout:
var timeoutValue = 15000; /*ms*/
setTimeout(function(){...}, timeoutValue);
which in you case could look like:
var close = function(element){element.hide();};
$('iframe').on('iframeclick', function(){
var timeoutValue = 15000;
var context = $(this);
setTimeout(function(){close(context)}, timeoutValue);
});
Binding event listeners to elements inside the iframe will only work if both the parent site and the iframe are on the same domain. If the contents of the iframe is on a different domain, you won't be able to perform this as it is classed as "click-jacking", which is a big security threat. See http://en.wikipedia.org/wiki/Same-origin_policy
If the iframe is on the same domain then you can add the event listener inside the iframe and then call the parent to notify the event.
You can also grab the contents and find the element you want to bind the event handler on.
$("iframe#name").contents().find(".link").on("click", function() {
$("iframe#name").delay(15000).hide();
});
Related:
How to add click event to a iframe with JQuery
Click-event on iframe?
Bind to events inside dynamically created iframe
Ways to circumvent the same-origin policy
Detect click inside iframe (same domain/sub domain) in Chrome using jQuery
I used sleep () function and solved my problem!

What is alternative for onload for <a>?

I have this HTML:
<a onmouseover="coverLookout(this,0)" style="width:100%;overflow:hidden" href="#jtCr4NsVySc" class="youtube">
<img id="video_642" style="width:100%;margin-left:0;max-width:100%;visibility:visible" src="https://img.youtube.com/vi/jtCr4NsVySc/mqdefault.jpg">
<span></span>
</a>
And js:
var yt=new Array('maxresdefault.jpg','mqdefault.jpg');
var coverLookout = function(block,i){
console.log(i);
var code=$(block).attr('href').toString().substr(1);
var url = "https://img.youtube.com/vi/" + code + "/" + yt[i];
$(function($){
$.ajax({
url: "function_js.php?page=check_img",
data: {"url":url},
cache: false,
success: function(response){
console.log(response);
if(response=="200"){
$(block).find("img").attr('src',url);return;
}else{
coverLookout(block,++i);
}
}
});
});
};
How can I use coverLookout function while *a* is loading instead of onmouseover? *A* onload doesn't work because onload I can use only with *body*. But how do onload for other tags?
A onload doesn't work because onload I can use only with body. But how do onload for other tags?
No, it works for elements that have a load event. a doesn't have a load event because it never has something to load. All a content is inline. load relates to things like images and scripts and stylesheets and such, that load a separate resource.
img has a load event, if you're talking about the image inside the link loading. You have to be sure to hook the event before setting the img source (the onload attribute works), or check the complete flag on the element if hooking the event later to see if it's already done.
From the comments below, it sounds like you want to change the img's source when the link is clicked. You can do that like this:
<a onclick="document.getElementById('video_642').src = '/new/src/here.png' ...
...or as you're using jQuery, this will handle all youtube links:
$("a.youtube").click(function() {
$(this).find("img").attr("src", "/new/src/here.png");
});
But the user may not see it, because when the link is followed, the browser tears down the page right away. You can improve the chances your user will see it if you make sure it's already in cache, by putting it on your page somewhere but hidden:
<img style="display: none" src="/new/src/here.png">
...so the browser has it in cache to display it before tearing down the page.
I want to while page is loading src in img will be changed by script
You mean when the page these links are on is loading? Okay. This would go in a script tag at the end of the body (just before the closing </body> element:
// Find all images within a.youtube links and change their `src`
$("a.youtube img").each(function() {
var img = $(this);
// Save current src so we can put it back later
img.attr("data-real-src", this.src);
// Set new source
this.src = "/new/src/here.png";
});
// Then when the page is done loading...
$(window).on("load", function() {
// Restore the original `src` values on the images
$("img[data-real-src]").each(function() {
var img = $(this);
img.attr("src", img.attr("data-real-src")).removeAttr("data-real-src");
});
});
onload Function works only with <body> so after document loading (under $(document).ready() function collect all a tags and call the function based on their index.
var els = document.getElementsByTagName("a");
for(var i = 0, l = els.length; i < l; i++) {
coverLookout(els[i],i);
}

Using jquery to control the iframe URL [duplicate]

I have an iframe on a page, coming from a 3rd party (an ad). I'd like to fire a click event when that iframe is clicked in (to record some in-house stats). Something like:
$('#iframe_id').click(function() {
//run function that records clicks
});
..based on HTML of:
<iframe id="iframe_id" src="http://something.com"></iframe>
I can't seem to get any variation of this to work. Thoughts?
There's no 'onclick' event for an iframe, but you can try to catch the click event of the document in the iframe:
document.getElementById("iframe_id").contentWindow.document.body.onclick =
function() {
alert("iframe clicked");
}
EDIT
Though this doesn't solve your cross site problem, FYI jQuery has been updated to play well with iFrames:
$('#iframe_id').on('click', function(event) { });
Update 1/2015
The link to the iframe explanation has been removed as it's no longer available.
Note
The code above will not work if the iframe is from different domain than the host page. You can still try to use hacks mentioned in comments.
I was trying to find a better answer that was more standalone, so I started to think about how JQuery does events and custom events. Since click (from JQuery) is just any event, I thought that all I had to do was trigger the event given that the iframe's content has been clicked on. Thus, this was my solution
$(document).ready(function () {
$("iframe").each(function () {
//Using closures to capture each one
var iframe = $(this);
iframe.on("load", function () { //Make sure it is fully loaded
iframe.contents().click(function (event) {
iframe.trigger("click");
});
});
iframe.click(function () {
//Handle what you need it to do
});
});
});
Try using this : iframeTracker jQuery Plugin, like that :
jQuery(document).ready(function($){
$('.iframe_wrap iframe').iframeTracker({
blurCallback: function(){
// Do something when iframe is clicked (like firing an XHR request)
}
});
});
It works only if the frame contains page from the same domain (does
not violate same-origin policy)
See this:
var iframe = $('#your_iframe').contents();
iframe.find('your_clicable_item').click(function(event){
console.log('work fine');
});
You could simulate a focus/click event by having something like the following.
(adapted from $(window).blur event affecting Iframe)
$(window).blur(function () {
// check focus
if ($('iframe').is(':focus')) {
console.log("iframe focused");
$(document.activeElement).trigger("focus");// Could trigger click event instead
}
else {
console.log("iframe unfocused");
}
});
//Test
$('#iframe_id').on('focus', function(e){
console.log(e);
console.log("hello im focused");
})
None of the suggested answers worked for me. I solved a similar case the following way:
<iframe id="iframe_id" src="http://something.com" allowtrancparency="yes" frameborder="o"></iframe>
The css (of course exact positioning should change according to the app requirements):
#iframe-wrapper, iframe#iframe_id {
width: 162px;
border: none;
height: 21px;
position: absolute;
top: 3px;
left: 398px;
}
#alerts-wrapper {
z-index: 1000;
}
Of course now you can catch any event on the iframe-wrapper.
You can use this code to bind click an element which is in iframe.
jQuery('.class_in_iframe',jQuery('[id="id_of_iframe"]')[0].contentWindow.document.body).on('click',function(){
console.log("triggered !!")
});
This will allow you to target a specfic element in the iframe such as button or text fields or practically anything as on method allows you to put selector as an argument
$(window).load(function(){
$("#ifameid").contents().on('click' , 'form input' , function(){
console.log(this);
});
});
Maybe somewhat old but this could probably be useful for people trying to deal with same-domain-policy.
let isOverIframe = null;
$('iframe').hover(function() {
isOverIframe = true;
}, function() {
isOverIframe = false;
});
$(window).on('blur', function() {
if(!isOverIframe)
return;
// ...
});
Based on https://gist.github.com/jaydson/1780598
You may run into some timing issues depending on when you bind the click event but it will bind the event to the correct window/document. You would probably get better results actually binding to the iframe window though. You could do that like this:
var iframeWin = $('iframe')[0].contentWindow;
iframeWin.name = 'iframe';
$(iframeWin).bind('click', function(event) {
//Do something
alert( this.name + ' is now loaded' );
});
This may be interesting for ppl using Primefaces (which uses CLEditor):
document.getElementById('form:somecontainer:editor')
.getElementsByTagName('iframe')[0].contentWindow
.document.onclick = function(){//do something}
I basically just took the answer from Travelling Tech Guy and changed the selection a bit .. ;)
Solution that work for me :
var editorInstance = CKEDITOR.instances[this.editorId];
editorInstance.on('focus', function(e) {
console.log("tadaaa");
});
You can solve it very easily, just wrap that iframe in wrapper, and track clicks on it.
Like this:
<div id="iframe_id_wrapper">
<iframe id="iframe_id" src="http://something.com"></iframe>
</div>
And disable pointer events on iframe itself.
#iframe_id { pointer-events: none; }
After this changes your code will work like expected.
$('#iframe_id_wrapper').click(function() {
//run function that records clicks
});

Showing iFrame only after its source content has been completely loaded

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.

running jquery functions in an iframe with hash links

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!');
}

Categories