I've got a piece of JavaScript that inserts/removes an iframe from the DOM. Everything is dandy in Chrome and FireFox but the iframe is not displayed in IE. The code below is the creation and insertion. When inspecting with a Developer tools I can see that the iframe is part of the DOM exactly as I expected it to be. Any suggestion on what might cause it not to be displayed?
function getiFrame(target) {
var frame = document.getElementById(target);
if (null == frame) {
frame = document.createElement("iframe");
frame.setAttribute("width", "100%");
frame.setAttribute("height", "1000px");
//frame.setAttribute("frameborder", "0");
frame.setAttribute("id", target);
frame.setAttribute("name", target);
frame.setAttribute("src", "http://dmi.dk");
} else {
frame.src = "http://dmi.dk";
frame.style.visibility = "visible";
}
return frame;
}
var frame = getiFrame(target);
var row = document.getElementById(contentRowId);
for (var i = 0; row.childNodes.length > 0; i++) {
row.removeChild(row.childNodes[0]);
}
row.appendChild(frame);
EDIT:
To clarify I've tryed setting the attributes directly (as suggested by Tim Down) the above was the result of my desperate attempts.
Further when inspecting the DOM I get a perfectly valid iframe tag:
<iframe propdescname="full" width="100%" height="1000" id="full" src="http://dmi.dk">
and inspecting that also shows that it's read and parsed the src (http://dmi.dk) correctly. I can inspect the DOM of that site too.
So what puzzles me is that when everything seems to work. What might stop it from being displayed.
There's one obvious problem:
frame = document.createElement("div");
should be
frame = document.createElement("iframe");
Also, setAttribute is unnecessary, verbose and error-prone in IE. Use DOM properties instead:
frame.width = "100%";
frame.height = 1000;
//frame.frameBorder = 0;
frame.id = target;
frame.name = target;
frame.src = "http://vrk.dk";
Jim Coplien referres to this as the Rubber Duck pattern. "You cannot ask xx before You've consulted the rubber duck". Who hasn't solved there own question while asking some one for advice.
I'was editing my post writing that the iframe was in a td and came to think that I hadn't made sure it actually was. The issue turned out to be me removing the td and inserting the iframe into the tr which IE incidentally handles differently when done dynamically than when done statically.
Thanks for listening in, playing the role of "the rubber duck"
Related
I am trying to figure out how to name/rename iframes with javascript.
function sesamOpenU(){
x = document.querySelector('iframe');
x.style.height= '200px';
x.style.width= '400px';
x.name = 'myFrame1' ;
let url = 'https://www.example.com/'
let other = window.open(url,'myFrame');
}
<iframe name ="myFrame">
</iframe>
<button onclick= "sesamOpenU()">Sesam, open U</button>
First, i tried to name an iframe without a name with x.name after defining x.
no errors in the console, but no result either.
I named the iframe manually to target it, and it works.
Then I tried to rename it with Javascript, but again, no result.
For ruling things out, I decided to adjust the height and width for reference to see if it would adjust.
It does.
I tried the adjustments before the function, no result. (widht and heigh does, name doesn't)
Can someone shine a light on my problem?
Edit: yes, i know that i have targeted myFrame, and not myFrame1 in the example. It was the last step of testing which one it would take. The named version, or the renamed version. The named version works, the renamed version doesn't ( opens the webpage in a new tab)
edit: solved.
Testing locally showed differences between Firefox and Chrome - Firefox happily opened the url supplied to window.open in the iframe with the same name as the browsing context supplied as the second argument. Chrome did not and would open the url in a new tab.
A possible workaround might be to set the src attribute of the iframe element directly:
function sesamOpenU(){
x = document.querySelector('iframe');
x.style.height= '200px';
x.style.width= '400px';
x.name = 'myFrame1' ;
let url = 'https://www.example.com/'
// let other = window.open(url,'myFrame1');
x.src = url;
}
This seems to work in both Firefox and Chrome, whether using example.com or the business site url provided in the original posted.
The code does reassign the name of your iframe but the way you set the source does not seem to be working.
I tried the following which seem to be working:
function sesamOpenU(){
x = document.querySelector('iframe');
x.style.height= '200px';
x.style.width= '400px';
x.name = 'myFrame1' ;
let url = 'https://www.example.com/';
x.src = url;
}
<iframe name ="myFrame">
</iframe>
<button onclick= "sesamOpenU()">Sesam, open U</button>
Note: your code does not work in an SO snippet, at least on my system, it gives this error:
js:26 Blocked opening 'https://www.alternate.nl/' in a new window
because the request was made in a sandboxed frame whose 'allow-popups'
permission is not set.
So I have tried it as a complete piece of code, see below.
It works fine with renaming the iframe - as long as you go back to having a url that will allow itself to be in a iframe - somehow your original url has been replaced by one that won't work - and whether or not the iframe had another name to begin with. Maybe there was some typo problem in the original code given which we missed? Anyway, all is well:
Here is the full code:
<!doctype html>
<html>
<head>
<title>Test iframe</title>
</head>
<body>
<iframe name='myFrame'></iframe>
<button onclick= "sesamOpenU()">Sesam, open U</button>
<script>
function sesamOpenU(){
x = document.querySelector('iframe');
x.style.height= '200px';
x.style.width= '400px';
x.name = 'myFrame1' ;
let url = 'https://www.alternate.nl/'
let other = window.open(url,'myFrame1');
}
</script>
</body>
</html>
I have an iframe that is generated in JavaScript with createElement() when a function is fired, which becomes a text editor. It works just fine in Chrome, Safari and Edge, but in Firefox, the innerHTML text, "Text Layer", will briefly flash within the iframe and then it disappears and the iframe doesn't seem to be editable. Upon inspection, the iframe's body tag is empty. If I set contentEditable to true on the iframe's body tag in the inspector it seems to work properly, but when I try to set this in my JS function, nothing happens in Firefox.
I'm guessing this has something to do with the iframe being created in JavaScript, since setting the designMode of an iframe already in the DOM to 'On' with JS seems to work properly. Wondering if there's a way to get this to work in Firefox, maybe another method of creating the iframe? I have seen some similar problems that were solved by putting some javascript in the iframe's src, as in the comments here, but that apparently causes problems in other browsers. Creating the iframe in JS is preferable to appending it from somewhere.
function text() {
var rtf = document.createElement("iframe");
rtf.name = "richTextField";
rtf.id = "richTextField";
rtf.className = "texteditor";
var dwrap = document.createElement("div");
dwrap.appendChild(rtf);
var tframe = document.getElementById("richTextField");
tframe.contentWindow.document.designMode = 'On';
tframe.contentWindow.document.body.innerHTML = "Text Layer";
tframe.contentWindow.document.getElementsByTagName('body')[0].focus();
tframe.onload = autosize();
};
Found this 15 year old bug report and was able to get it work by setting the contentWindow properties inside of a setTimeout function.
function text() {
var rtf = document.createElement("iframe");
rtf.name = "richTextField";
rtf.id = "richTextField";
rtf.className = "texteditor";
var dwrap = document.createElement("div");
dwrap.appendChild(rtf);
var tframe = document.getElementById("richTextField");
setTimeout(function(){
tframe.contentWindow.document.designMode = 'On';
tframe.contentWindow.document.body.innerHTML = "Text Layer";
tframe.contentWindow.document.getElementsByTagName('body')[0].focus();
}, 0);
tframe.onload = autosize();
};
I've written a bookmarklet (with a little help from the experts at Stackexchange) and I've run into a small little issue where I can't close the thing.
Here's the code (sensitive people should probably move on):
javascript: (function () {
var htmlheader = "<html><head></head>"
var html = htmlheader + "<body><a href='javascript:document.getElementById(\"TroubleiFrame\").style.visibility = \"hidden\"'>Close</a>" +
"</body></html>";
var iframe = document.createElement('iframe');
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
iframe.style.background = "#fff";
iframe.style.width = "50%";
iframe.style.height = "500px";
iframe.style.left = "25%";
iframe.style.top = "25vh";
iframe.style.position = "fixed";
iframe.style.zIndex = "9999";
iframe.id = "TroubleiFrame";
iframe.style.boxShadow = "0 0 0 100vw rgba(0,0,0,0.75)";
document.body.appendChild(iframe);
})();
When clicking on the close link I get this error:
Uncaught TypeError: Cannot read property 'style' of null
If I paste the command in Chromes console it works:
document.getElementById("TroubleiFrame").style.visibility = "hidden"
Do you have any ideas on what I'm doing wrong? If possible I'd love a brief explanation too so I'm learning something from it.
/Patrik
Your iFrame doesn't know about an element called "TroubleiFrame" since it is in a child window.
You need to call the parent instead, and from there you can close it
parent.document.getElementById("TroubleiFrame");
Look at this question to see how to close the iFrame properly. Right now you're just going to hide it
I've also came across this problem creating a bookmarklet just like Pinterest's Pin It.
It should work cross-domain.
The only way I could work this out, was by posting events between the page inside the iframe and the parent page following this example on GitHub:
https://gist.github.com/kn0ll/1020251
I've posted an answer on this other thread:
https://stackoverflow.com/a/43030280/3958617
And also found one more example on this other thread:
https://stackoverflow.com/a/21882581/3958617
Hope it helps!
Hi I am adding a iframe dynamically, It displays an image from a server. I need to disable the context menu for this item. In chrome I can inspect element and if I add oncontextmenu="return false" I do get the wanted affect. However I am unable to do this while the page is generated. Here is an example of the working html.
However I can not reproduce this when i frame is being created. Here is my code.
$(window).scrollTop(0);
$('#secVerify').show();
$("#popWaitLoad").modal("hide");
imgLoading.hide();
dvIframe.empty();
//else load deposit data into interface
$("#spanType").text(deposit.DepositType);
$("#spanReference").text(deposit.Reference);
$("#spanAmount").text("R " + deposit.Amount.toFixed(2));
$("#spanDate").text(deposit.DateCreatedOffsetS);
imageID = deposit.Deposit_Doc_imageID;
var url = imageUrl + '/' + deposit.Deposit_Doc_imageID + '/false';
var imgFrame = document.createElement("iframe");
imgFrame.src = url;
imgFrame.frameBorder = '0';
imgFrame.scrolling = 'no';
imgFrame.width = '100%';
imgFrame.height = '100%';
imgFrame.align = 'middle';
imgFrame.id = "iframeImg";
dvIframe.append(imgFrame);
I have tried examples like.
$("#iframeImage").contents().find("img").attr("oncontextmenu", 'return false');
$('#iframeImage img').on('contextmenu', function (e) {
e.stopPropagation();
// Your code.
return false;
});
But because the img element seems to be only created is done after page load it seems to not work. I know disabling the the menu will not help much and I have explained all the other methods of obtaining the image that is still available but the client really wants this.
I have added nocontextmenu to the body tag and it works everywhere except for the iframe.
So let me clarify, My iframe is working like it should however I would like to disable the right click aka context menu on the specific iframe.
I have used setAttribute to set the attributes and targeted a container to appendChild.
function example(){
var target = document.getElementById('container');
var element = document.createElement('img');
element.setAttribute('src', 'http://gopalshenoy.files.wordpress.com/2011/04/product_demos.jpg');
//element.setAttribute('width','100%');
//element.setAttribute('height','100%');
element.setAttribute('id','iframeImage');
element.setAttribute("oncontextmenu","return false;");
target.appendChild(element);
}
// Demo-Snippet use.
window.onload=example;
<!-- Demo Snippet use -->
<div id="container"></div>
If you build more than one element using this function you might find further issues due to duplicated ID's.
ID's are used to target a specific element 'one of' so if you want to build multiple elements I would recommend giving them unique ID's.
I hope this helps. Happy coding!
There is a border showing on an iframe and I can't get rid of it.
IE 6 and 7 work as intended with a little JavaScript:
function test(){
var iframe = document.getElementById('frame2');
iframe.contentWindow.document.body.style.backgroundColor = "#a31d1d";
iframe.contentWindow.document.body.style.border = "#a31d1d";
iframe.contentWindow.document.body.style.outlineColor = "#a31d1d";
}
But the border remains visible in IE 8.
Add following attributes to iframe tag:
marginheight="0" marginwidth="0" frameborder="0"
I had the same problem with iframes created dynamically, and it turned out that setting border properties AFTER adding the iframe to the document has NO effect:
The following code shows a 3d border:
var iframe = document.createElement("IFRAME");
iframe.src = "http:www.stackoverflow.com";
//Iframe added BEFORE setting border properties.
document.body.appendChild(iframe);
iframe.frameBorder = "no";
But this actually removes it:
var iframe = document.createElement("IFRAME");
iframe.src = "http:www.stackoverflow.com";
iframe.frameBorder = "no";
//Iframe added AFTER setting border properties.
document.body.appendChild(iframe);
Hope that this would help solve your problem.
I tried loads of variations on this idea and ended up using something along these lines. Thought I'd share it.
<script type="text/javascript">
url = 'http://www.dollypower.com';
title = 'Dolly Power';
width = '660';
height = '430';
document.write('<iframe src='+url+' title='+title+' width='+width+' height='+height+' frameborder=0></iframe>');
</script>
Then I used noscript tags to enter an alternative for non-JS users, i.e:
<noscript><p>Please click here for Dolly Power</p></noscript>
I tested it in IE8 and it's all cool for me and it also validates.
Hope this might help someone out there!
Success!
Try this. It will find any iframe elements and remove their borders in IE and other browsers (though you can just set a style of "border : none;" in non-IE browsers instead of using JavaScript). AND it will work even if used AFTER the iframe is generated and in place in the document (e.g. iframes that are added in plain HTML and not JavaScript)!
This appears to work because IE creates the border, not on the iframe element as you'd expect, but on the CONTENT of the iframe--after the iframe is created in the BOM. ($#&*##!!! IE!!!)
Note: The IE part will only work (of course) if the parent window and iframe are from the SAME origin (same domain, port, protocol etc.). Otherwise the script will get "access denied" errors in the IE error console. If that happens, your only option is to set it before it is generated, as others have noted, or use the non-standard frameBorder="0" attribute. (or just let IE look fugly--my current favorite option ;) )
Took me MANY hours of working to the point of despair to figure this out...
Enjoy. :)
// =========================================================================
// Remove borders on iFrames
if (window.document.getElementsByTagName("iframe"))
{
var iFrameElements = window.document.getElementsByTagName("iframe");
for (var i = 0; i < iFrameElements.length; i++)
{
iFrameElements[i].frameBorder="0"; // For other browsers.
iFrameElements[i].setAttribute("frameBorder", "0"); // For other browsers (just a backup for the above).
iFrameElements[i].contentWindow.document.body.style.border="none"; // For IE.
}
}
Sample HTML to go with the sample JS would be helpful =)
Try using IE8's Developer Tools (press F12 on the page you have problems with) to isolate what styles are being applied to the iframe. You can also play with the styles there, to cut down your iteration time.
Keep in mind that this may be IE not respecting border settings in the css, whereas the traditional setting of the attribute BORDER=0 on the iframe element may work. Worth a test, at least.
Edit: It looks like what does fix the problem is setting frameborder='0' on the iframe element. That worked for me, at least.
If you want your code to validate you could do this with javascript. I found the perfect answer when I had this problem a few months ago here
var iframe = document.createElement("iframe");
iframe.src = "banner_728x90.gif";
iframe.width = "728";
iframe.height = "90";
iframe.frameBorder = "0";
iframe.scrolling = "no";
document.body.appendChild(iframe);
f you want to load another page seamless in the iframe you can do this if you copy and paste this code into the head of your page. I found it on a site with free scripts. The performance is good in most cases
function getDocHeight(doc) {
doc = doc || document;
var body = doc.body, html = doc.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
return height;
}
function setIframeHeight(id) {
var ifrm = document.getElementById(id);
var doc = ifrm.contentDocument? ifrm.contentDocument: ifrm.contentWindow.document;
ifrm.style.visibility = 'hidden';
ifrm.style.height = "10px"; // reset to minimal height in case going from longer to shorter doc
ifrm.style.height = getDocHeight( doc ) + 10 + "px";
ifrm.style.visibility = 'visible';
}
You then give your iframe an id and call the script on load. This is how.
var iframe = document.createElement("iframe");
iframe.setAttribute('id', "ifrm1");
iframe.setAttribute('src', 'http://www.hekcmviw.com/'); // change the URL
iframe.setAttribute('width', '100%');
iframe.setAttribute('height', '10');
iframe.setAttribute('frameBorder', '0');
iframe.setAttribute('scrolling', 'no');
iframe.setAttribute('onload' ,"setIframeHeight(this.id)");
document.body.appendChild(iframe);