Mobile Safari and iFrame src attribute - javascript

I am trying to set the 'src' attribute for an iFrame. It works great on FireFox and Internet Explorer. However, when testing on iPad mobile safari changing the 'src' attribute doesn't do anything.
I have an iFrame that has it's 'src' attribute set in the HTML.
<iframe id="iFrame0" style="margin: 0px; overflow: hidden; padding: 0px; height:80px; width:500px" src='.../loading.gif' frameborder="0"></iframe>
Later on I have some code that tries to change the src
var iFrame0 = YAHOO.util.Dom.get('iFrame0');
YAHOO.util.Event.addListener(iFrame0, 'load', function() { alert('test'); });
MyWebService.GetDynamicUrl('someparam', function(url) {
iFrame0.src = url;
});
Not only does the event not fire, but the content of the URL doesn't change. In my testing I noted that the value iFrame0.src does change to the newly passed in URL, but the content on the page does not change.
I am using YUI, however, to eliminate that as a potential problem in my testing I have also tried to directly access the iFrame via:
document.getElementById('iFrame0').attribute("src") = '..../newurl.gif';
Still doesn't work.

In the end I solved this by dynamically creating the iframe and attaching it to the DOM. I also added a timestamp to the id and src attributes in order ensure no caching is being done (though I'm unsure if that truly is necessary).
var elIFrame = document.createElement("iframe");
var dt = new Date();
elIFrame.src = APP_IMAGEPATH + "/loading.gif?dt=" + dt.getTime();
elIFrame.id = 'newCard2' + dt.getTime();
elIFrame.frameBorder = 0;
elIFrame.scrolling = "no";
elIFrame.style.width = "500px";
elIFrame.style.height = "1.8em";
YAHOO.util.Dom.insertAfter(elIFrame, this.pre + "cardMask");

Are you sure that the variable iFrame0 is actually pointing the iFrame DOM object and not some empty object or other element using the same ID (a DIV for example)? Maybe you could try to check the initial src to see if it's what you expect (i.e. '.../loading.gif').
Try to access the frame with the following:
var frameObj = document.frames ? document.frames['iFrame0'] : document.getElementById('iFrame0'),
frameWin = frameObj.contentWindow || frameObj;
And then try to modify its src:
frameWin.src = '..../newurl.gif';

Related

How to traverse an HTML document loaded using iframe? [duplicate]

<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
<html>
<head></head>
<body class="frameBody">
test<br/>
</body>
</html>
</iframe>
What I want to get is:
test<br/>
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, easy readable and even afaik the shortest way to get the iframes content.
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 uses the contentDocument property and that is the reason why we proof this property first in this OR condition. If it is not set 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.
Using JQuery, try this:
$("#id_description_iframe").contents().find("body").html()
it works perfectly for me :
document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
AFAIK, an Iframe cannot be used that way. You need to point its src attribute to another page.
Here's how to get its body content using plane old javascript. This works with both IE and Firefox.
function getFrameContents(){
var iFrame = document.getElementById('id_description_iframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
alert(iFrameBody.innerHTML);
}
use content in iframe with JS:
document.getElementById('id_iframe').contentWindow.document.write('content');
I think placing text inbetween the tags is reserved for browsers that cant handle iframes i.e...
<iframe src ="html_intro.asp" width="100%" height="300">
<p>Your browser does not support iframes.</p>
</iframe>
You use the 'src' attribute to set the source of the iframes html...
Hope that helps :)
Chalkey is correct, you need to use the src attribute to specify the page to be contained in the iframe. Providing you do this, and the document in the iframe is in the same domain as the parent document, you can use this:
var e = document.getElementById("id_description_iframe");
if(e != null) {
alert(e.contentWindow.document.body.innerHTML);
}
Obviously you can then do something useful with the contents instead of just putting them in an alert.
The following code is cross-browser compliant. It works in IE7, IE8, Fx 3, Safari, and Chrome, so no need to handle cross-browser issues. Did not test in IE6.
<iframe id="iframeId" name="iframeId">...</iframe>
<script type="text/javascript">
var iframeDoc;
if (window.frames && window.frames.iframeId &&
(iframeDoc = window.frames.iframeId.document)) {
var iframeBody = iframeDoc.body;
var ifromContent = iframeBody.innerHTML;
}
</script>
To get body content from javascript ,i have tried the following code:
var frameObj = document.getElementById('id_description_iframe');
var frameContent = frameObj.contentWindow.document.body.innerHTML;
where "id_description_iframe" is your iframe's id.
This code is working fine for me.
If you want to not just select the body of your iframe, but also insert some content to it, and do that with pure JS, and with no JQuery, and without document.write(), I have a solution that no other answer provides.
You can use the following steps
1.Select your iframe:
var iframe = document.getElementById("adblock_iframe");
2.Create an element that you want to insert into the frame, let's say an image:
var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
img.style.width = "200px";
img.style.height = "50px";
} else {
img.style.width = "400px";
img.style.height = "100px";
}
img.id = "image";
3.Insert the image element into the iframe:
iframe.contentWindow.document.body.appendChild(img);
You can get the contents of the iframe body in one line of code:
document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerText;

Change iframe src through js

So coming straight to the problem, i am writing a js which should change the src of iframe if screen resolution changes
<script language="javascript">
function newframe()
{
var w = screen.width;
var srchframe = document.getElementById("proj");
var targetURL1 = "http://wms.indianpropertynetwork.com/exchange/frames/clients.featured_projects.asp?cnt=5&wd=880&prj=1";
var targetURL2 = "http://lpm.indianpropertynetwork.com/exchange/frames/clients.featured_projects.asp?cnt=4&wd=668&prj=1";
if (srchframe.src != targetURL1 && w > 1300 )
{srchframe.src = targetURL1 }
else
{ srchframe.src = targetURL2 }
}
</script>
and calling this function in the following iframe
<iframe id="proj" onload="newframe();" marginwidth="0" marginheight="0" width="100%" height="200px" frameborder="0" scrolling="No" ></iframe>
The problem with script is it keeps on loading both the url in alternate order and won't stop loading.
You are using onload handler to start another load cycle, so continuously reloading is what your code seems to be intended to do.
Your code:
What to do on page load in iframe? Call newFrame().
This is in your code reading onload="newframe();"
newFrame() is setting frames src causing it to load another page.
Your if is assigning new URL to src of srchframe on any invocation of newframe(). And for it's loading URL 1 if current isn't URL 1 and URL 2 otherwise it is actually resulting in swapping both URLs.
Due to having switched pages in 2. another onload event will be triggered.
The essential problem is: by assigning URL to srchframe.src that frame's page gets replaced to load another one. So don't adjust the src property of iframe unless it is actually intended to load another page this way.
Basically you should try different approach. Take it as described initially:
should change the src of iframe if screen resolution changes
So you shouldn't bind to onload event of iframe, but to onresize event of outer window. Even though this isn't acting on changing screen resolution it is all better than your approach. Eventually try media queries as proposed in my answer to this post: https://stackoverflow.com/questions/23198520/website-adapting-to-different-monitor-sizes/23198630#23198630
Execute your function only once as onLoad is called on every change of src , for this purpose you can do with the help of a bool, below is the code you can use:
HTML:
<script language="javascript">
var newFrameCalled = false;
function newframe()
{
if(newFrameCalled)
return;
var w = screen.width;
var srchframe = document.getElementById("proj");
var targetURL1 = "http://wms.indianpropertynetwork.com/exchange/frames/clients.featured_projects.asp?cnt=5&wd=880&prj=1";
var targetURL2 = "http://lpm.indianpropertynetwork.com/exchange/frames/clients.featured_projects.asp?cnt=4&wd=668&prj=1";
if (srchframe.src != targetURL1 && w > 1300 )
{srchframe.src = targetURL1 }
else
{ srchframe.src = targetURL2 }
newFrameCalled = true;
}
</script>
Hope this helps.

Acess iframe content (in firefox plugin javascript)

I'm writing a firefox plugin who open an iframe in webpages. I want to select object in the iframe, but i can't access content:
var iframe = content.document.getElementById("MyBeautifulIframe");
if (iframe)
{
var mydiv = iframe.contentDocument.getElementById("mydiv");
}
Erreur : TypeError: iframe.contentDocument is undefined
I tryed with iframe.content.document.getElemen... , iframe.document.getElemen... same result.
How access iframe dom ? If i look iframe var type, it's [object XrayWrapper [object XULElement]], how access dom objects of XULElement object ?
Updated answer:
Took a look at your code and i think i may have found your problem.
You are doing:
var iframe = content.document.getElementById("muzich_iframe_addcontainer");
if (iframe)
{
if (iframe.contentDocument.getElementById("div"))
{
this.close_all();
}
}
muzich_iframe_addcontainer is a div, not the iframe, so it never has contentDocument.
Additionally, i couldn't make it work by creating xul elements. I had to create html div and iframe to make it work.
Here's the code:
var htmlns = "http://www.w3.org/1999/xhtml";
var container = document.createElementNS(htmlns,'div');
container.setAttribute("id", "muzich_iframe_addcontainer");
container.setAttribute("style", styleContainer); //styleContainer is the one you use without the background stuff
window.content.document.body.appendChild(container);
var iframe = document.createElementNS(htmlns,'iframe');
iframe.setAttribute("id", "muzich_iframe");
iframe.setAttribute("style",
"width: 100%; height: 100%; "
);
iframe.setAttribute("src", "http://www.lifehacker.com"); // Used it as my example url
window.content.document.getElementById("muzich_iframe_addcontainer").appendChild(iframe);
Then, when you want to check to close you do:
var iframe = window.content.document.getElementById("muzich_iframe");
if (iframe)
{
if (iframe.contentDocument.getElementById("div"))
{
this.close_all();
}
}
Hope this one solves it for you.

Reload iframe src / location with new url not working in Safari

I have a page that loads with initially just a form within an iframe, something like this:
<iframe id="oIframe" ...src='somePage>'
<form ... />
</iframe>
When you click a button in the form, some javascript is invoked that builds a url and then I want to do the following:
frame.src = 'somePage?listId=1';
This works in IE to "reload" the frame with the new contents.
However, in Safari this does not work.
I have jQuery available, but I don't want to replace the existing iframe because there are events attached to it. I also can not modify the id of the iframe because it is referenced throughout the application.
I have seen some similar issues but no solutions that seem to work well for my exact issue.
Any assistance anyone can provide would be great!
Some browsers don't use "src" when calling the javascript object directly from the javascript hierarchy and others use "location" or "href" instead of "src" to change the url . You should try these two methods to update your iframe with a new url.
To prevent browser cache add a pseudo-random string like a number and timestamp to the url to prevent caching. For example add "new Date().getTime()" to your url.
Some calling examples:
document.getElementById(iframeId).src = url;
or
window.frames[iframeName].location = url;
I recommend the first option using document.getElementById
Also you can force the iframe to reload a page using
document.getElementById(iframeId).reload(true);
So the answer is very simple:
1. put a <div id="container"> </div> on your page
2. when reload needed use following jQuery:
$("#container").empty();
$("#container").append("<iframe src='" + url + "' />");
and that's it.
Of course there is more elegant way of creating DOM with jQuery but this gives the idea of "refreshing" iframe.
Works in FF18, CH24, IE9, O12 (well it's jQuery so it will work almost always :)
I found a better solution (albeit not paticularly eloquent) for this using jQuery.ajax:
jQuery.ajax({
type: 'GET',
url: "/somePage?someparms",
success: function() {
frameObj.src = "/somePage?someparms";
}
});
This forces the DOM to be read within the frame object, and reloads it once the server is ready to respond.
Try this
form.setAttribute('src', 'somePage?listId=1');
Well, I was able to find what appears to be a feasible solution -- it's a work in progress, but this is basically what I ended up doing:
var myFrame = document.getElementById('frame'); // get frame
myFrame.src = url; // set src attribute of original frame
var originalId = myFrame.id; // retain the original id of the frame
var newFrameId = myFrame.id + new Date().getTime(); // create a new id
var newFrame = "<iframe id=\"" + newFrameId + "\"/>"; // iframe string w/ new id
myFrameParent = myFrame.parentElement; // find parent of original iframe
myFrameParent.innerHTML = newFrame; // update innerHTML of parent
document.getElementById(newFrameId).id = originalId; // change id back
I ran into this issue using React, passing the key as props.src solved it
const KeyedIframe = ({children, ...props}) => <iframe key={props.src} { ...props}>
{children}
</iframe>

How to get the body's content of an iframe in Javascript?

<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
<html>
<head></head>
<body class="frameBody">
test<br/>
</body>
</html>
</iframe>
What I want to get is:
test<br/>
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, easy readable and even afaik the shortest way to get the iframes content.
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 uses the contentDocument property and that is the reason why we proof this property first in this OR condition. If it is not set 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.
Using JQuery, try this:
$("#id_description_iframe").contents().find("body").html()
it works perfectly for me :
document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
AFAIK, an Iframe cannot be used that way. You need to point its src attribute to another page.
Here's how to get its body content using plane old javascript. This works with both IE and Firefox.
function getFrameContents(){
var iFrame = document.getElementById('id_description_iframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
alert(iFrameBody.innerHTML);
}
use content in iframe with JS:
document.getElementById('id_iframe').contentWindow.document.write('content');
I think placing text inbetween the tags is reserved for browsers that cant handle iframes i.e...
<iframe src ="html_intro.asp" width="100%" height="300">
<p>Your browser does not support iframes.</p>
</iframe>
You use the 'src' attribute to set the source of the iframes html...
Hope that helps :)
Chalkey is correct, you need to use the src attribute to specify the page to be contained in the iframe. Providing you do this, and the document in the iframe is in the same domain as the parent document, you can use this:
var e = document.getElementById("id_description_iframe");
if(e != null) {
alert(e.contentWindow.document.body.innerHTML);
}
Obviously you can then do something useful with the contents instead of just putting them in an alert.
The following code is cross-browser compliant. It works in IE7, IE8, Fx 3, Safari, and Chrome, so no need to handle cross-browser issues. Did not test in IE6.
<iframe id="iframeId" name="iframeId">...</iframe>
<script type="text/javascript">
var iframeDoc;
if (window.frames && window.frames.iframeId &&
(iframeDoc = window.frames.iframeId.document)) {
var iframeBody = iframeDoc.body;
var ifromContent = iframeBody.innerHTML;
}
</script>
To get body content from javascript ,i have tried the following code:
var frameObj = document.getElementById('id_description_iframe');
var frameContent = frameObj.contentWindow.document.body.innerHTML;
where "id_description_iframe" is your iframe's id.
This code is working fine for me.
If you want to not just select the body of your iframe, but also insert some content to it, and do that with pure JS, and with no JQuery, and without document.write(), I have a solution that no other answer provides.
You can use the following steps
1.Select your iframe:
var iframe = document.getElementById("adblock_iframe");
2.Create an element that you want to insert into the frame, let's say an image:
var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
img.style.width = "200px";
img.style.height = "50px";
} else {
img.style.width = "400px";
img.style.height = "100px";
}
img.id = "image";
3.Insert the image element into the iframe:
iframe.contentWindow.document.body.appendChild(img);
You can get the contents of the iframe body in one line of code:
document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerText;

Categories