Define an event on iFrame element with jQuery - javascript

I try to define a live event on img tags store on a iFrame. For example, I would like obtain a simple javascript alert box when I click a image on my iFrame.
Do you know how i can define the events for the iFrame, because I would like to put a thing like $('img').live("click",function().... but only for the elements on iFrame.
Please note: img tags are dynamically added on my iFrame after page load.
Thanks for your help.
Nicolas

You can do it if you
make sure that the page in the iframe has its own copy of jQuery loaded [ed.: only really necessary for jQuery operations internal to the frame's page itself]
from the outer document, work into the iframe document like this:
$('#iframeId').contents().find('img') // ...

The other solutions here are largely myopic, as what you are trying to do is fairly complicated in the underlying javascript.
I'd suggest using jquery context as well - and I'd strongly suggest waiting for the iframe to totally load or else none of the previous suggestions could work anyway...
$("#frame").ready(function () { //wait for the frame to load
$('img', frames['frame'].document).bind("click",function(){
alert('I clicked this img!');
});
});
This should generally work UNLESS you update the iframe or refresh it, in which case all the event bindings will fail... and worse yet the .live events don't appear to be supported in iframes - at least not for me.

$("iframe").contents().find("img")
This will target images within the iFrame. But be aware that jquery will only traverse the iFrame if it is not a violation of the browser's (or jquery's) cross-site policy.
That means if the iframe is google.com, you can't touch the inner DOM.

jQuery.bind() won't work with external documents. At least in jQuery 1.6.2.
However you can bind to DOM events:
$("iframe").contents().find("img").onclick = function() { // do your staff here };
If you do not have full list of images at the moment, you can use events propogation:
$("iframe").contents().find("body").onclick = function() { // do your staff here };
It will work event with custom events:
$("iframe").contents().find("body").onmyevent = function() { // do your staff here };
One more thing to remember... frame content is loaded asynchronously. So bind your handlers AFTER your iframe content is loaded:
var $iframe = $("iframe");
$iframe.bind("load", null, funcion(e) {
$iframe.contents().find("body").onclick = function() { // do your staff here };
});
For more complicated cases handle your images clicks inside iframe, and trigger your custom events that you can later handle on the body level. Especially if you have totally dynamic content and want to bind to 'live' events inside iframe.

you can fire event innner like this:
parent.$('#dlg').trigger('onTitle');
then hold event like this:
$('#dlg').bind('onTitle', function(){ alert(); });

this worked for me. NB: make sure you have referenced jquery library on the iframe page as well.
$(document).ready(function(){
$('#iframeid').load(function(){ //make sure that all elements finish loading
$('#iframeid').contents().find('img').live({
click: function(){
alert('clicked img');
}
});
});
});

Related

How to bind a future event when using jQuery Mobile external page linking?

In jQuery Mobile, the external page is linked via Ajax (i.e. the content of the external page is loaded into current page via Ajax).
The problem is: How to bind a event on the future (i.e. to be loaded) content?
Let say the content to be loaded has the following HTML input
<input type='text' id='foo' name='foo'>
How to bind a input event on it?
With just static HTML, the following code would work
$('#foo').on('input', function () {
...
Now it didn't work now since the DOM is loaded dynamically, I tried to use delegation but also not work
$(document).on('#foo', 'input', function () {
...
Any idea?
You can include the script in the external page as long as the script tag is within the data-role="page" div (Only the content of the first found data-role="page" element is loaded into the current page.
$(document).on("pagecreate", "#extpagedivid", function(){
$(document).on("input", "#foo", function(){...});
});
You can also include this code in the pagecreate handler of the main page as long as you are using event delegation. Make sure the ID of the input is unique across all pages that will be loaded into the main page.
How about using var
var myFunc = function() { ... }
$(document).ready(function() {
$('#foo').on('input', myFunc );
});

editing a Div that is around an iframe via jquery from within said iframe

I'm sure this sounds a little odd, but here's the background...
We utilize a company that loads their chat program, so we can support our customers, into our page. This is done via javascript and jquery, and creates a structure like this:
<div id="myid" style="...; right: 0px;..."><div><iframe></iframe></div></div>
There's a WHOLE lot more to that, but those are the important parts. Now the tool allows us to put custom scripting, which will be placed in the iframe. My goal is to just remove the "right: 0px", which I have done via the below code, but I don't want to put that code on every page that this tool integrates with. I would like to load it into the tool, and have it run when the iframe and divs are created.
working code on parent:
$(document).ready(function() {
function checkPos() {
$('#myId').each(function() {
var oldstyle = $('#myId').attr('style');
var newstyle = oldstyle.replace(' right: 0px;','');
$('#myId').attr('style', newstyle);
});
setTimeout(checkPos, 100);
};
$(document).ready(function() {
setTimeout(checkPos, 100);
});
});
Once placed in the code include method they provide, I have trouble having it wait until the div tag actually has the "right: 0px;" in its style tag. the only thing I need to run is the three lines in the $('#myId').each(function()
Basically, I need help with having the script in the iframe target the div that the iframe is nested in.
Assuming that whatever tool your using actually lets you pass in a custom script to the content rendered in the iframe (seems fishy to me), a better way of modifying the style in jquery is to use the css function:
$('#myId').css('right', '0px');
Notice I removed the $.each function as well. You are targeting an element with an id, so there isn't any need to iterate.
Edit:
Anyways, back to the problem of delaying execution to when the target, #myId, actually exists. If they are really injecting your javascript into their page (again, seems fishy), then attaching the above code to the $(document).ready() event should do the trick, as long as this listener is attached to their document.
If all else fails, try to use the waitUntilExists plugin, here:
Source:
https://gist.github.com/buu700/4200601
Relevant question:
How to wait until an element exists?

Check if iframe is loaded inside $(document).ready

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.

Using jQuery to update content within an iFrame live & on-the-fly...?

I'm using an iframe to display a website next to a form. I want to update certain content within that iframe live based upon the value of the various input fields.
This is what I'm trying to do (working outside of an iframe): http://jsfiddle.net/YkKUS/
The textarea will be outside of the iframe and the content that'll be updated will be inside the iframe.
Here is my code adapted to work with my iframe:
$('.liveDemoFrame').load( function(){ // load the iframe
$(this.contentDocument).find('h1').html($('textarea').val());
$('textarea').keyup(function() {
$(this.contentDocument).find('h1').html($(this).val()); // this line is screwing something up?!?
});
});
The 5th line is causing me some problems. The iframe DOES actually update successfully with the content of my textarea but only when I refresh the page. It's not updating it live & on-the-fly which is the only reason I'm doing this!
Thanks!
I did this in the parent page and it seemed to work:
$(document).ready(function(){
$('#textarea').bind('keyup', function() {
var iframedoc = $('#iframe').get(0).contentDocument;
$(iframedoc).find('h1').html($(this).val());
});
});
There might be some kinks with jQuery, or you might be doing it incorrectly. Either way, it could be easiest to actually run half of your code within the iframe; then you can call iframe.contentWindow.getHtml(), or iframe.contentWindow.setHtml(), if you can. Also IIRC, the contentDocument was not standard either; some browsers require contentWindow.document or similar.
However, the main culprit would be this:
$('.liveDemoFrame').load( function(){
$(this.contentDocument).find('h1').html($('textarea').val());
$('textarea').keyup(function() {
// here this refers to textarea dom element, not iframe
$(this.contentDocument).find('h1').html($(this).val());
});
});
Fix could be like
$('.liveDemoFrame').load( function(){
var iframeDocument = $(this.contentDocument);
iframeDocument.find('h1').html($('textarea').val());
$('textarea').keyup(function() {
// here this refers to textarea dom element, not iframe
iframeDocument.find('h1').html($(this).val());
});
});
You can't do stuff in the iframe from outside of it, that would be a massive security hole

Calling Javascript in a page after it's been loaded by jQuery GET

Imagine a normal page calling javscript in head. The trouble is some of the content isnt loaded untill i click on a link. Subsequently when this link loads the content it wont work. This is because i guess the javascript has already been run and therefor doesnt attach itself to those elements called later on. There is only standard html being called.
So for example this is the code which calls my external html.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).slideDown('slow');
});
});
If the html i was calling for example and H1 tag was already in the page the cufon would work. However because i am loading the content via the above method H1 tags will not be changed with my chosen font.This is only an example. The same will apply for any javascript.
I was wonering whether there is a way around this without calling the the javascript as well the html when its received from the above function
If you want to attach events to elements on the page that are dynamically created take a look at the "live" keyword.
$('H1').live("click", function() { alert('it works!'); });
Hope this is what you were looking for.
Does Cufon.refresh() do what you want?
As you said Cufon was just an example, I'd also suggest a more general:
$.get(url, options, function(html, status) {
var dom = $(html);
// call your function to manipulate the new elements and attach
// event handlers etc:
enhance(dom);
// insert DOM into page and animate:
dom.hide();
$target_element.append(dom); // <-- append/prepend/replace whatever.
dom.show(); // <-- replace with custom animation
});
You can attach event handlers to the data that you get via the get() inside of the callback function. For example
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).find('a').click(function(e) {
// specify an event handler for <a> elements in returned data
}).end().slideDown('slow');
});
});
live() may also be an option for you, depending on what events you want to bind to (since live() uses event delegation, not all events are supported).
Andy try this. It will call the Cufon code after each AJAX request is complete and before the html is actually added to the page.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data);
Cufon.replace('h1');
$(this).slideDown('slow');
});
});
JavaScript is not executed because of a security reason OR beccause jQuery is just setting this element's innerHTML to some text (which is not interpreted as a JavScript) if it's contained. So the security is the beside effect.
How to solve it?
try to find all SCRIPT tags in Your response and execute them as fallows:
var scripts = myelement.getElementsByTagName("SCRIPT");
var i = 0;
for (i = 0; i < scripts.length; i++)
eval(scripts[i].innerHTML);

Categories

Resources