iframe with dynamically defined url is empty - javascript

I need to set a URL to iframe dynamically, but when I do so, the iframe is empty.
Here is the iframe's definition:
<html:iframe id="myFrame" width="700px" height="500px"></html:iframe>
And here how I tried to set the URL:
var sRedirectUrl = "http://google.com"; //dynamically defined url
var sIframeId = this.getView().byId(this.createId("myFrame")).getId();
$("#"+sIframeId).attr("src",sRedirectUrl);
Here is jsbin example.
I also tried to do the following:
Definition:
<IconTabFilter id="iframe_container">
</IconTabFilter>
Url set:
var sRedirectUrl = "http://google.com"; //dynamically defined url
this.getView().byId(this.createId("iframe_container")).addContent(
new sap.ui.core.HTML({
content: "<iframe scr=\""+sRedirectUrl+"\" width='700px' height='700px'></iframe>"
})
);
And it doesn't work also.
What am I missing here?
Thank you.
UPDATE
Hard coding a generated link into iframe is working fine:
<html:iframe id="myiframe" src="https://generated_link_to_some_site.com?uniqueId"></html:iframe>

You are doing right, but Google does not allow iFrame, try with test.com in your jsbin instead and it will work : http://jsbin.com/vuqujoxupe/1/edit?html,output

The reason why iframe was empty is very simple - I tried to call the element before it was rendered.
It took me 3 days to realize that. Don't be like me.

Related

Get the iframe name from the source document

I have following iframe in a parent page:
<html>
....
<iframe src="child.html" name="variedName" id="variedId"></iframe>
...
</html>
Is there any way that make Javascript from child.html to get the name value or the id of the iframe that included it?
I need this because I want to add some markup around the iframe that is going to include child.html in the parent page using window.parent
Well, the quick and dirty solution would be to give the iframe the same name and id and access the iframe within the child page like this:
parent.document.getElementById(window.name);
Yes, but only if the pages share the same origin.
You can do something like:
var parent_window = window.parent;
iframes = parent_window.document.getElementsByTag("iframe");
if (iframes[0].window === window) {
// found it
}
The if statement might need some tweaking but I think this works.
Besides the presented solutions, You can use this:
parent.document.getElementsByName(window.name)[0];
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByName
Or this:
parent.document.querySelector('iframe[src="'+location+'"]');
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector
Or this "frankencode":
(function(){
for(var i=0,frames=parent.frames,l=frames.length;i<l;i++)
{
if(frames[i].window===window)
{
return frames[i].window;
}
}
})();
If you have jQuery:
$('iframe[name="'+window.name+'"]',parent); //method 1
$('iframe[src="'+location+'"]',parent); //method 2
$('iframe',parent).filter(function(){ //a different method
return this.window===window;
}).eq(0);
And many more ways...

How can I access to an iframe DOM?

I just want to access to the DOM in an iframe.
I can display in the Chrome console to the whole iframe definition with the code below :
$('document').ready(function(){
var toto = window.parent.$("#compare_package")[0];
console.log(toto);
});
But I don't find the solution to access to the '#document' content.
I tried :
var toto = window.parent.$("#compare_package")[0].contentDocument;
or :
var toto = window.parent.$("#compare_package")[0].contentWindow;
But it does not work.
Does anyone can help me ?
Thanks in advance for your help.
it only works in same origin policy
// you iframe
<iframe id="some" src=""></iframe>
// bind after iframe content is loaded
$("#some").contents().find('.item');

Cannot get width of DIV in AngularJS modal window

I put this code into the index.html file or the view (html) file in my AngularJS web app and it works like a charm:
<div id="chart"></div>
<script>
var chart = document.getElementById("chart");
alert("width is : " + chart.offsetWidth);
</script>
I can resize my browser window and when I refresh, it tells me the new width.
However, when I put this code in with the code for a modal window in the view (html) file, I get "width is : 0"
Does anybody know why and how I can get the width of a DIV in a modal window?
The question is old but in case you or someone else haven't figured it out yet:
You need to make sure you get the value you're looking for AFTER the element(s) have been rendered. Otherwise you will always get '0'
That is why in jQuery you wrap your code in a block like this:
$(function() {
// your code here
});
There are a few variants of this;
In pure JS you would use 'document.onLoad'
If you're using jQuery you can use
$('#chart').width()
http://api.jquery.com/width/

Why does JavaScript injected in a iframe use the parent window as its global scope?

With an Ajax call I get a "blob" of content that I need to inject in an iframe. I've no control over the content... it might be only HTML or HTML + JavaScript.
As a "template" I use an empty html file as my iframe src. Upon the "load" event of the iframe, I push the blob into its body. It mostly works (using jQuery):
$iframe.contents().find('body').html(my blob);
What happens is that the "window" object of the JS injected with this system is the window.top, the parent window. Why?
I think the problem might be related on how jQuery html() works, but I can't figure out a cross browser way to do the same operation w/o using jQuery.
Any help is appreciated.
Edit: this is the very minimal case:
<iframe id="z" src="scene.html"></iframe>
<script>
var xxx = 13;
$("#z").load(function() {
var c = "<scri" + "pt>console.log(xxx)</scr" + "ipt>";
$(this).contents().find('body').append(c);
})
</script>
In the console we read "13" (and I do not access the javascript objects that are already present in scene.html).
Add this to your scene.html:
function myAppendFunc(html) {
$('body').append(html);
}
Then call it from outside:
$("#z").load(function() {
var c = "<scri" + "pt>console.log(xxx)</scr" + "ipt>";
this.contentWindow.myAppendFunc(c);
})
That should work.

Reload an IFRAME without adding to the history

I'm changing an IFRAME's src in order to reload it, its working fine and firing the onload event when its HTML loads.
But it adds an entry to the history, which I don't want. Is there any way to reload an IFRAME and yet not affect the history?
Using replace() is only an option with your own domain iframes. It fails to work on remote sites (eg: a twitter button) and requires some browser-specific knowledge to reliably access the child window.
Instead, just remove the iframe element and construct a new one in the same spot. History items are only created when you modify the src attribute after it is in the DOM, so make sure to set it before the append.
Edit: JDandChips rightly mentions that you can remove from DOM, modifiy, and re-append. Constructing fresh is not required.
You can use javascript location.replace:
window.location.replace('...html');
Replace the current document with the
one at the provided URL. The
difference from the assign() method is
that after using replace() the current
page will not be saved in session
history, meaning the user won't be
able to use the Back button to
navigate to it.
Like Greg said above, the .replace() function is how to do this. I can't seem to figure out how to reply to his answer*, but the trick is to reference the iFrames contentWindow property.
var ifr = document.getElementById("iframeId");
ifr.contentWindow.location.replace("newLocation.html");
*Just learned I need more reputation to comment on an answer.
An alternative method to recreating the iframe would be to remove the iframe from the DOM, change the src and then re add it.
In many ways this is similar to the replace() suggestion, but I had some issues when I tried that approach with History.js and managing states manually.
var container = iframe.parent();
iframe.remove();
iframe.attr('src', 'about:blank');
container.append(iframe);
One solution is to use the object tag rather than the iframe tag.
Replacing this:
<iframe src="http://yourpage"/>
By this:
<object type="text/html" data="http://yourpage"/>
will allow you to update the data attribute without affecting the history. This is useful if you use a declarative framework such as React.js where you are not supposed to do any imperative command to update the DOM.
More details on differences between iframe and object: Use of Iframe or Object tag to embed web pages in another
Try to use this function to replace old iframe with new iframe which is copied from old one:
function setIFrameSrc(idFrame, url) {
var originalFrame = document.getElementById(idFrame);
var newFrame = document.createElement("iframe");
newFrame.id = originalFrame.getAttribute("id");
newFrame.width = originalFrame.getAttribute("width");
newFrame.height = originalFrame.getAttribute("height");
newFrame.src = url;
var parent = originalFrame.parentNode;
parent.replaceChild(newFrame, originalFrame);
}
Use it like this:
setIFrameSrc("idframe", "test.html");
This way will not add URL of iframe to browser history.
Use the replace method to bypass the addition of the iframe's URL to history:
HTML:
<iframe id="myIframe" width="100%" height="400" src="#"></iframe>
JavaScript:
var ifr = document.getElementById('mIframe')
if (ifr) {
ifr.contentWindow.location.replace('http://www.blabla.com')
}
JDandChips answer worked for me on a cross origin iframe (youtube), here it is in vanilla JS (without JQuery):
const container = iframe.parentElement;
container.removeChild(iframe);
iframe.setAttribute('src', 'about:blank');
container.appendChild(iframe);
The most simple and fast loading solution
Use window.location.replace to not update the history when loading the page or the frame.
For links it looks like this:
<a href="#" onclick="YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>
or
<a href="javascript:YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>
But if you want it not to act from link but to act automatically when loading the frame then from the iframe you should put this in the iframe file body section:
onload="window.location.replace ('http://www.YourPage.com');"
If for some reason the onload does not load in the iframe then put your target frame name instead of window in the syntax like this:
onload="YourTarget.location.replace ('http://www.YourPage.com');"
NOTE: For this script all onclick, onmouseover, onmouseout , onload and href="javascript:" will work.
#JDandChips has a great answer above, but the syntax should be updated from parent() to parentElement:
var container = iframe.parentElement;
iframe.remove();
iframe.attr('src', 'about:blank');
container.append(iframe);

Categories