recognizing actions on an iframe - javascript

So I have an iframe, and I would like to be able to do something like an alert whenever a specific button in the iframe is clicked. But the following code does not work
$('.class_name').click(function(){
alert('Clicked');
});
in fact, it wont even alert when the iframe is clicked (which is the same code as above, but where .class_name becomes iframe).
I looked at the solution from this question, and it still did not work!
This is a jsfiddle that should demonstrate the issue pretty well.
So my question is: Why wont Jquery recognize when anything inside the iframe, as well as the actual iframe, is clicked?
Edit:
I understand that I cannot communicate with an iframe on a different domain, so my jsfiddle wont work...but it doesn't work on the site where I am hosting it on the same domain as the iframe...

If your iframe is coming from a different domain, as in your fiddle, then your JavaScript code has no access to its contents at all, sorry!
As #Max poins out, you can use postMessage() or the URL fragment hack to communicate with an iframe in a different domain, if there is code in that iframe to handle this communication from that side.
With an iframe from tumblr.com, you could check their documentation to see if it talks about using this page in an iframe and communicating with it across the domain barrier.
Now if you're talking about an iframe from the same domain as your page, then it's easy. Given an iframe element in a variable named myframe, you can use myframe.contentWindow to get its window object and myframe.contentWindow.document to get its document object. From there you can do the things you need. For example:
var $myframe = $('#myframe'),
myframe = $myframe[0],
myframewin = myframe.contentWindow,
myframedoc = myframewin.document;
$(myframedoc).find('a').on( 'click', function() {
alert( 'Clicked!' );
});
You may still have some trouble using a copy of jQuery in the main page to access things in the iframe, but should have better luck with the latest versions. Worst case you can use native DOM events and methods for this, but jQuery does work in this updated fiddle.
This fiddle uses document.write to put content in the iframe, but the jQuery code accessing the frame would be the same either way. The one thing to watch out for, of course, is whether the iframe has been completely loaded when you try to access it.
I think you can listen for a load event on the iframe element in the containing page, but worst case you could use setTimeout() or setInterval() and wait for the elements you're looking for to become available.

Because the iFrame is a completely different frame- it's done out of security concerns. For example, imagine if you could load a banks login page in an iFrame, and use js to get the field values.
With different domains especially, it is much harder to communicate with JS- this should get you started: How to communicate between iframe and the parent site?

Related

iframe setting content

I have been searching for this for days and was wondering if anyone could help me with the answer to this.
So, I am currently building a system which allows users to create html pages which can include css and js links and possibly inline scripts/styles within it.
I want the user to preview their output, i was originally using a div tag and adding the html output to it but as all the extra styles and scripts also affected the parent page, i decided the only option was probably to use an iframe to put the content in.
To stop bootstrap links and Jquery conflicts to the parent element, i need to run the iframe in a sandbox environment from what i know but i have no idea how to set the content of the iframe when its in sandbox mode.
If you try:-
$("example iframe element").contents().find("body").html("example html inline styles etc");
this does not work and blocks access due to the iframe being sandboxed and not allowing the origin.
Sandboxing an iframe seems to be the only way to stop multiple instances of Jquery "one on the parent and one in the iframe" from conflicting, i did try noConflict which seems to work but that does not fix conflicting multiple bootstraps being loaded in the parent and iframe elements.
does anyone know either how to add content at runtime to a iframe that is sandboxed without getting blocked access or a different unique container approach i can use?
i appreciate any help or guidance anyone could give on this as i cannot really find much information about it.
I have finally found out what the problem is with this situation, i do not need a sandboxed iframe as i now know why Jquery and Bootstrap are conflicting without having to sandbox the iframe. I see lots of posts telling you to use something like the code below to put content in an iframe.
$("example iframe element").contents().find("body").html("example html inline styles etc");
the problem with the method above is that its opening the iframe up for putting content inside it but its not specifying the closing of the iframe.
This is why even on a normal none sandboxed iframe Jquery and Bootstrap conflict because its leaking back into your parent page by not being closed. The real method for putting content into an iframe directly should be the code below as it ensures the connection is closed off appropriately.
var myIframe = document.getElementById("ID OF THE IFRAME")
var iframeDoc = myIframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write("HTML HERE");
iframeDoc.close();
by doing the above code you are not only modifying the content inside the iframe but your also closing it off once you have finished writing the content. This is very important in ensuring Iframes stick to their purpose as being a completely isolated page element and it stops js and css leaks into your parent page.
i hope this answer helps save time for anyone else who comes across this particular problem with iframes and is adding content at run time using the wrong method.

How to use `arrive.js` to find an element arrived inside of a `iFrame'

I require to find the DOM element which is adding inside of a iframe, with the iframe added. for determine to find the element added, I am using this plugin
all i doing from chrome ext.
arrive.js
body>iframe1>iframe.ssueContentIframe2>#SmartReportTabContent1>loopElements>link
like this:
document.arrive(".ssueContentIframe", function() {
console.log('.ssueContentIframe arrived', this);//works
this.arrive('#SmartReportTabContent1', function(){
console.log('arrive 2');//not working
});
});
what is wrong here? any one help me please?
To check for an element within an iframe you need to include the arrive.js library and your script that calls the arrive() function within the iframe.
If you just want to detect whether iframe is loaded there's other solutions, but if you want to muck around in the iframe you have to keep in mind cross-domain policies.
Javascript has a Same-Origin policy in which javascript on the outer page cannot access the contentWindow or DOM (or global state) of the iframe page if it does not share the Same-Origin
-- T. Stone
Seems to me arrive.js isn't the problem, it's trying to mess with an iframe.

Iframe inside Iframe cant do changes

I have one iframe inside on iframe and with this code i want to change the src of an image
window.top.frames[0].frames[0].document.getElementById("maquina").src = "https://developer.cdn.mozilla.net/media/img/mdn-logo-sm.png";
and when i try it it work but i cant see changes in the page, only in code when e read .src
of that element
You cannot manipulate the contents of an iframe from within the parent frame without a global method for accessing the child DOM. There is an answer Here that suits your needs, but I will copy below for reference:
In the child iframe:
parent.childGetElementById = function (id) {return document.getElementById(id);}
parent.childLoaded();
In the parent:
function childLoaded() {var dom = childGetElementById('someid');}
Assuming you actually have access to the child page, I would recommend modifying your design away from the use of iframes.
[Answering the comment]
Well it depends on if you're just using straight HTML, or a scripting language (like PHP). If pure HTML, you can use a server side includes with
<!-- #include virtual="path/to/included/file.html" -->
In PHP, you can include the page like this
require('/real/path/to/included/file.php');
Don't get me wrong, iFrames can be useful in some specific situations (circumventing cross-domain origin policies, oAuth implementations, etc); they are more often abused than correctly used.

Included JS in iframe has context of top frame window

$('<script/>', {
src: '/path/to/javascript.js',
type: 'text/javascript'
}).appendTo($('#iframe').contents().find('body'));
Correct me if I'm wrong, but I think that should load the JS into the iframe. I've also tried appending to head.
The problem
javascript.js is executed, but console.debug(this) in that script returns the top frame window. I've tried to verify that the script is actually included in the iframe, but don't really know how.
Additionally, running $('a') from javascript.js returns all links in the top frame, not every link in the iframe which I'd like.
Thanks for your time!
Update: I've put together an isolated test case which you also can download. Check the console and note that this is the top frame (can be verified by the variable _TOP).
This is kind of a grey area. For this specific action using jQuery, under the hood you're using importNode or adoptNode depending on the browser. However, IE won't support either (since I last researched it).
You might want to get a reference to the document, and write the script. If memory serves me right:
$('<iframe/>')[0].contentDocument.document.write('script');
I was able to make something in the same domain iframe update:
http://jsfiddle.net/maniator/DX6bg/1/
Make sure that the two URLs are in the same domain.
(including if there is a www in from or not)
UPDATE
You can test it like this:
$(function(){
var iframe = $('#iframe').contents();
$('body', iframe).append($('<div>', {text: 'this is a test'}));
});
now if you see the text this is a test in the iframe you know it is working

Javascript popups, can I reference all js on the parent page like normal?

Are all popups the same when it comes to referencing the parent pages js variables/methods etc?
How about ajax requests from within the popup's content?
From what i understand a popup is just playing with the Z-order, so its basically still on the parents page just looks 'higher' right?
Most likely you're talking about a popup being a div (or other element) being displayed when an action occurs. this is done by having some sort of hidden element on the page that just gets displayed and maybe centered, then brought to the front (using the z-index).
if this is how you're using popup's with javascript then yes, all javascript that's on the page is accessible to the popup.
You will have to be cognizant of cross-domain scripting. However, for the simplest cases, you should be able to reference javascript on the parent page with:
if (window.parent)
{
window.parent.SomeFunctionOnParent();
}
Javascript popups are independent windows but they can refer to their owner via: window.owner

Categories