I have one entire html openning inside an iframe that contains a javascript function getData().Now I am not sure how to call getData() from outside that frame.Also is it possible to call it from an external javascript file ?
You can get a reference to the frame window object from the window.frames property. See https://developer.mozilla.org/en/DOM/window.frames
UPDATE:
You can access the global context of a named iframe with window[framename]. e.g:
<iframe src="data.html" name="data"></iframe>
<script>
var myData = window.data.getData();
</script>
Although you will need to make sure the iframe has loaded.
In jQuery you can use the contents method if you want access to the iframe DOM:
$("iframe").contents()
All this is assuming the frame hosted within the same domain.
UPDATE[2]:
You asked if it is possible to call the getData function from an external js file. The answer is yes (if I understand you correctly). Here is an example:
<html>
<head>
<meta charset="utf-8">
<title>parent page</title>
</head>
<body>
<iframe src="data.html" name="data"></iframe>
<script src="getdata.js"></script>
</body>
</html>
Then in the getdata.js file you have:
var dataFrame = window.data;
// when the frame has loaded then call getData()
dataFrame.onload = function () {
var myData = dataFrame.getData();
// do something with myData..
}
Hope this answers your question :)
In certain situation there could be a neccessity of calling a javascript function inside an iframe from the parent document, and vice versa ie;
calling a javascript function in parent document from the iframe.
For example; the parent document have an iframe with id attribute ‘iFrameId‘, and the function ‘functionInIframe()‘ is defined in that iframe document.
Following code can call that iframe function from the parent document itself.
document.getElementById('iFrameId').contentWindow.functionInIframe();
And following code can call the function defined in parent document(functionInParent()) from the iframe itself.
parent.functionInParent();
This way javascript can interact between parent document and iframe.
This is the original post.
in these cases you name your iframe and the main body that uses/launches frame and then use parent.objectname, in JS everything is Object and you should be able to call getData()
a quick googling led me to this -> http://www.esqsoft.com/javascript_examples/iframe_talks_to_parent/
Related
I have this HTML code:
<html>
<head>
<script type="text/javascript">
function GetDoc(x)
{
return x.document ||
x.contentDocument ||
x.contentWindow.document;
}
function DoStuff()
{
var fr = document.all["myframe"];
while(fr.ariaBusy) { }
var doc = GetDoc(fr);
if (doc == document)
alert("Bad");
else
alert("Good");
}
</script>
</head>
<body>
<iframe id="myframe" src="http://example.com" width="100%" height="100%" onload="DoStuff()"></iframe>
</body>
</html>
The problem is that I get message "Bad". That mean that the document of iframe is not got correctly, and what is actualy returned by GetDoc function is the parent document.
I would be thankful, if you told where I do my mistake. (I want to get document hosted in IFrame.)
Thank you.
You should be able to access the document in the IFRAME using the following code:
document.getElementById('myframe').contentWindow.document
However, you will not be able to do this if the page in the frame is loaded from a different domain (such as google.com). This is because of the browser's Same Origin Policy.
The problem is that in IE (which is what I presume you're testing in), the <iframe> element has a document property that refers to the document containing the iframe, and this is getting used before the contentDocument or contentWindow.document properties. What you need is:
function GetDoc(x) {
return x.contentDocument || x.contentWindow.document;
}
Also, document.all is not available in all browsers and is non-standard. Use document.getElementById() instead.
In case you get a cross-domain error:
If you have control over the content of the iframe - that is, if it is merely loaded in a cross-origin setup such as on Amazon Mechanical Turk - you can circumvent this problem with the <body onload='my_func(my_arg)'> attribute for the inner html.
For example, for the inner html, use the this html parameter (yes - this is defined and it refers to the parent window of the inner body element):
<body onload='changeForm(this)'>
In the inner html :
function changeForm(window) {
console.log('inner window loaded: do whatever you want with the inner html');
window.document.getElementById('mturk_form').style.display = 'none';
</script>
You can also use:
document.querySelector('iframe').contentDocument
I have code that can be reduced to this:
<script>
function write_to_iframe(){
let nw = document.getElementById("mysrc");
let myframe = document.getElementById("myframe");
myframe.contentWindow.document.body.innerHTML = nw.innerHTML;
}
</script>
<iframe id="myframe" width="230" height="95"></iframe>
<div id="mysrc">
<script>
function hello(){
alert("hello world");
}
</script>
SayHello<br>
</div>
It writes the code in the div to the iframe. That part seems to work. However, when I click the SayHello link in the iframe I get a javascript error that the function hello() cannot be found.
What is going wrong here? And how can I declare an inline javascript function in the frame that works.
I am not interested in external javascript files or code that puts everything in the link (like onclick="javascript:alert('hi');").
I would reconsider using an iframe with innerHTML and trying to call a function in the main document from it. The support can vary in different browsers, iframes access to its parent is very limited. If both those things are on the same domain then you don't break CORS policy and you can do more but still there are better options.
If you insist on using iframe, I would consider creating an external path for it (same domain) ex. iframe/embed.html put HTML there normally, then change location after click triggered inside to iframe/embed.html#callHello. And in main document I would add eventListner to detect location change.
const iframe = document.getElementById("iframeId");
window.open("https://example.com/iframe/embed.html", "iframeId");
iframe.addEventListener("load", () => {
if (iframe.contentWindow.location.href.includes('#callHello')) {
hello();
}
});
Info: I was working on it for so long, I have a webpage that contains an iframe. Inside that iframe i have opened a page (application) from my own site.
Question: I'm trying to get the <div class = "ps-lightbox"> </ div> inside that iframe out of the iframe. but i cant figure it out with jQuery..
I know it sounds confusing. But I hope you understand my explanation.
Does anyone know how to fix this? You could save my day..
Screenshot of the webpage <
You can not access the elements which are not part of iframe document. But if you have iframe of your own website then window.postMessage can do the trick.
Consider below example:
mainPage.html
<html>
<head>
<script type="text/javascript">
window.addEventListener("message", function(evnet){
if(event.type === "GET_SOME_ELEMENT"){
var iframeWindow = document.getElementsById("iframe1")[0].contentWindow;
iframeWindow.postMessage("POST_SOME_ELEMENT", "TARGET_ORIGIN", {element: $(".some-element")}
}
});
<script/>
</head>
<body>
<div class="some-element"/>
<iframe id="iframe1" src="iframePage.html"/>
</body>
</html>
iframePage.html
<html>
<head>
<script type="text/javascript">
if(window.parent){
window.parent.postMessage("GET_SOME_ELEMENT", "TARGET_ORIGIN");
window.addEventListener("message", function(evnet){
if(event.type === "POST_SOME_ELEMENT"){
console.log(event.data.element);
}
});
}
<script/>
</head>
</html>
The exact question is how to do it with pure JavaScript, not with jQuery.
But I always use the solution that can be found in jQuery's source code. It's just one line of native JavaScript.
For me, it's the best, easily readable and even afaik the shortest way to get the content of the iframe.
First get your iframe
var iframe = document.getElementById('id_description_iframe');
// or
var iframe = document.querySelector('#id_description_iframe');
And then use jQuery's solution
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
It works even in the Internet Explorer which does this trick during
the contentWindow property of the iframe object. Most other browsers
use the contentDocument property and that is the reason why we proof
this property first in this OR condition. If it is not set to try
contentWindow.document.
Select elements in iframe
Then you can usually use getElementById() or even querySelectorAll() to select the DOM-Element from the iframeDocument:
if (!iframeDocument) {
throw "iframe couldn't be found in DOM.";
}
var iframeContent = iframeDocument.getElementById('frameBody');
// or
var iframeContent = iframeDocument.querySelectorAll('#frameBody');
Call functions in the iframe
Get just the window element from iframe to call some global functions, variables or whole libraries (e.g. jQuery):
var iframeWindow = iframe.contentWindow;
// you can even call jQuery or other frameworks
// if it is loaded inside the iframe
iframeContent = iframeWindow.jQuery('#frameBody');
// or
iframeContent = iframeWindow.$('#frameBody');
// or even use any other global variable
iframeWindow.myVar = window.myVar;
// or call a global function
var myVar = iframeWindow.myFunction(param1 /*, ... */);
Note
All this is possible if you observe the same-origin policy.
This might help you
var html = $(".ps-lightbox").contents().find("body").html()
And btw, you can get access to iframe's content only from the same origin due to XSS protection
Make sure your code is inside jQuery ready event.
// This won't work
$("#iframe").contents().find('.ps-lightbox');
// This will work
$(function() {
$("#iframe").contents().find('.ps-lightbox');
})
I am using javascript to open the species_county file in a new window/tab and then jquery to change the contents of an h1 tag with id speciesTitle.
open_event_test.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p>Click the button to open a new window called "MsgWindow" with some text. </p>
<button onclick="myFunction('Yada')">Yada</button>
<script>
function myFunction(species)
{
console.log(species);
var myWindow = window.open("species_county.html", species);
myWindow.document.getElementById("speciesTitle").html(species);
}
</script>
</body>
</html>
species_county.html
<!doctype html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<h1 id="speciesTitle">Species in County</h1>
</body>
</html>
I get error saying the element I'm grabbing has value null. I need to replace only some content. Document.write does not work because it will not open the species_county file, it will create an entirely new page.
There are a few possible issues with your script.
1) Elements Do Not Have html Method
As mentioned by beercohol, there is no such method as html() on an HTML Element. html() is a jQuery method, which is a property of a jQuery Object. In order to use this, you need to either use jQuery to select the element, or use JavaScript's native innerHTML property.
myWindow.document.getElementById("speciesTitle").innerHTML = species;
// or
$(myWindow.document).find('#speciesTitle').html(species);
2) The Window/Frame's DOM Has Not Loaded
There's a high chance that, by the time you've run the code to change the speciesTitle element, the window that you've opened has not yet finished loading its DOM. This would result in an error along the lines of:
TypeError: myWindow.document.getElementById(...) is null
You'll need to somehow make sure that you don't run the HTML-altering code until the DOM of the new window has finished loading. Traditionally, this is a job for jQuery, but here's a quick (non-cross-browser-friendly) pure JavaScript example within your myFunction method:
function myFunction (species) {
var myWindow = window.open("species_county.html", species);
myWindow.onload = function() {
// DOM has loaded
this.document.getElementById("speciesTitle").innerHTML = species;
}
}
3) Same Origin Policy
For security reasons, most browsers won't let you make adjustments to a window of another frame unless both frames come from the same origin. If you're working locally, the chances are you're not using a domain name or an IP address which match. Chrome doesn't let you make these communications over the filesystem (not by default anyway), but I have had some success with Firefox waiving Same Origin Policy between files locally on the file system. Either way, this won't work on a legitimate browser if you are attempting to communicate with a frame from a completely different domain.
For more information, see the window.open() FAQ on the MDN website. Note the part about cross-domain:
A script loaded in a window (or frame) from a distinct origin (domain
name) cannot get nor set properties of another window (or frame) or
the properties of any of its HTML objects coming from another distinct
origin (domain name).
4) Popup Blockers
It's also likely that you may run into trouble with various browser implementations of popup blockers. These will outright refuse to open the new frame, resulting in a null window object. You will first need to 'allow' your page to open a window through some configuration in the browser (usually a popup-blocker icon makes itself apparent).
The obvious problem is that html() is not a method of the Element object returned by getElementById()
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
https://developer.mozilla.org/en-US/docs/Web/API/Element
The property you're looking for is innerHTML instead.
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
Try this for your script:
<script>
function myFunction(species) {
console.log(species);
var myWindow = window.open("species_county.html", species);
myWindow.document.getElementById("speciesTitle").innerHTML = species;
}
</script>
html() is a jQuery function, so I suspect that's where you're getting confused. You don't really need jQuery just for this however, although you are including it.
You are trying to modify an element on a different page, and that's not possible with JavaScript in the way you're handling it.
One way to achieve your goal is to pass a $_GET parameter and use JavaScript on the newly loaded page to change the element.
Change this:
var myWindow = window.open("species_county.html", species);
myWindow.document.getElementById("speciesTitle").html(species);
To this:
var url = "species_county.html?species=" + encodeURIComponent(species);
window.open(url);
And then in species_county.html, look for the species parameter and change the title.
var mySpecies = location.search.split('species=')[1];
if(mySpecies !== undefined) {
document.getElementById("speciesTitle").innerHTML=mySpecies;
}
Unfortunately, shennan's 3rd idea was right, so I had to end up solving it like this:
open_event_test
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p>Click the button to open a new window called "MsgWindow" with some text.</p>
<button onclick="myFunction('Bombus balteatus')"><em>Bombus balteatus</em> Dahlbom</button>
<button onClick="myFunction('Bombus auricomus')"><em>Bombus auricomus</em> (Robertson)</button>
<script>
function myFunction(species)
{
var newhtml = '<!DOCTYPE html><head><meta charset="utf-8"><html><title>'+species+'</title></head><body><h1><em>'+species+'</em> in County</h1></body></html>';
var newWindow = window.open(species, '_blank');
newWindow.document.write(newhtml);
}
</script>
</body>
</html>
How to invoke a function in iframe using JS or how to even target the iframe? I've tried using document.getElementByID("myIframe"), but it didn't seem to work. Below is a basic form of the HTML:
<html>
<head>
<script>
function runFunction() {
var win = document.getElementByID("myIframe");
}
</script>
</head>
<body onload="runFunction()">
<iframe id="myIframe" name="myIframe" src="http://www.myothersite.com/"></iframe>
</body>
</html>
My other site has a function named getEvents() that I would like to somehow invoke. Any help would be greatly appreciated.
You should be able to access the iframe and invoke the function using the following:
// reference to window in iframe with id or name 'myIframe'
var win = window.frames['myIframe'];
// invoke function in win
win.getEvents();
You can use the contentWindow property which can be used to access the window object that belongs to a iframe element.
The contentWindow property returns the Window object by an iFrame element (through the Window object, you can access the document object and then any one of the document's elements). This DOM attribute is read-only.
document.getElementById("myIframe").contentWindow.getEvents();