Can't access iframe content in IE - javascript

I'm building a CMS application which I'm debugging now for IE. But things happen I cant comprehend.
First I have a div with the content of a page. I extract the content of the div and with javascript I create an iFrame and append that to the div. This is for making the WYSIWYG-editor. Then when I want to add the content to the iFrame the problems start. IE can't access the iFrame's body for some reason. I can alert the iFrame's document, which gives me [object Document] or [object HTMLDocument], but when I then alert the body I get null.
I use this function for getting the document as part of a javascript object:
iframedoc: function(aID) {
if (document.getElementById(aID).contentDocument){
return document.getElementById(aID).contentDocument;
} else {
var iFrame = document.getElementById(aID);
return iFrame.contentWindow.document;
}
},
and this is where I call it for the first time:
tas[i].innerHTML = "";
tas[i].appendChild(ta_edit_functions);
tas[i].appendChild(ta_edit);
tas[i].appendChild(ta_result);
alert(ta.iframedoc(ta_edit_id));
ta.iframedoc(ta_edit_id).body.innerHTML = ta_edit_content;
ta.iframedoc(ta_edit_id).designMode = 'on';
Here I empty the div, append a div containing the WYSIWYG-functions, the iFrame and the textarea for eventually submitting the form.
I'm testing in IE 8 and 9. Weirdest thing is that when I put an alert before first calling iframedoc in IE 8 I suddenly do get the body.
I would be really grateful if someone could at least point me in the right direction. I really don't have a clue what's happening.

I'm testing in IE 8 and 9. Weirdest thing is that when I put an alert before first calling iframedoc in IE 8 I suddenly do get the body.
That sounds as though you're going too fast for the browser -- the iframe is probably just not fully loaded yet when you try messing with it, so adding in an alert gives it the extra time it needs. Try deferring some of your code using an onload event on the iframe element.

Eventually my solution was using a interval function checking if the body of the iFrame is available.
But with those errors gone I found out that in IE8 turning on designmode for the iFrame removed all the content of it. So I ended up just using a contenteditable div..

Related

(Javascript) .click() an clickable div inside an iframe

Imagine the situation, where I have an iframe of a website.
Inside that website there is a button in which I want to click via javascript.
After looking into the HTML of the website, I noticed that the button is actually a div, with class like.
So I tried this:
function likeFunction()
{
var iframe = document.getElementById("myFrame");
var elmnt = iframe.contentWindow.document.getElementsByTagName("div")[10];
elmnt.click();
}
or
function likeFunction()
{
var iframe = document.getElementById("myFrame");
iframe.contentWindow.document.getElementsByTagName("div")[10].click();
}
and my final attempt was giving that div an ID='ex'
function likeFunction()
{
var iframe = document.getElementById("myFrame");
iframe.contentWindow.document.getElementById("ex").click();
}
But in the end, nothing really did it for me, any ideas?
Thanks in advance!
Your solution should work, as long as the iFrame is on the same domain. If it is not, you should get an error on this line
iframe.contentWindow.document.getElementsByTagName("div")[10].click();
So you would probably have noticed.
My only thoughts are:
you might be using the wrong selector,
you might be running the posted script on the iframe itself, not on the parent scope
you might be running this before the iFrame is loaded. Maybe running this onDocumentComplete on the parent document or some other way.
The click listener might be on on different element than the one you are progamatically clicking on.
But in the scenarios I mentioned, you should be getting an error, which you didn't mention.
Otherwise, the general approach works on my tests.

IE href="javascript:customFunction()" not firing on first frame load

I have a custom date picker popup that isn't working in IE sometimes. It works in Chrome and Edge fine.
The code looks something like this:
<frameset>
<frame>Buttons for next/prev month/year</frame>
<frame>This is the actual calendar that gets redrawn when the above buttons are used
1 //there's a different anchor tag for each day of the month
</frame>
<frameset>
So here's where it gets kind of weird. We have two networks, call them old and new. Old has probably a lot of undocumented global policy changes and new is probably close to the gov standard. This works on any browser on the old network, but not IE (11) on the new network. It works in Edge though. Additionally, if the top frame buttons are used to pick the next/prev month, or just the "Today" button, then all of the bottom frame anchor links work normally. There are no console errors/warnings, nothing in the network monitor showing a request returned an error code, the clicks just don't register. I put a breakpoint inside customFunction() and it won't break when the links don't work, but it will break if the link will work.
The only other thing that seems odd to me is that the code for the whole popup looks something like:
str = "<frameset><frame name='topFrame' " +
"src='javascript:parent.opener.drawTop'></frame><frame name='bottomFrame' "+
"src='javascript:parent.opener.drawBottom'><frame</frameset>"
document.write(str);
I did look to check and the code that redraws the bottom frame when the prev/next/etc buttons are used is the same function that gets called during the first load.
However, what seems odd about this is that on the first load the DOM inspector shows everything (top frame, bottom frame including all the individual numbers for each day of the month, etc), but the Debugger (F12 tools) doesn't show the code loaded with the document.write(str); line. To be able to see that code and set break points I have to use the prev/next buttons and then an additional .html file shows up in Debugger which has the constructed HTML that matches the DOM.
try this:
1)
1
2)
1
3)
1
4) check your code. Maybe your frame has attribute 'sandbox'. This attribute can block javascript. Example:
<iframe src="URL" sandbox>
Aside from the great suggestions by Nutscracker, I've also had my share of vague problems with document.write and event handlers not attaching in IE. The problem commented on by ConnorsFan could be the cause here, but you could also try:
document.body.innerHTML = '<frameset><frame name="topFrame" ' +
'src="javascript:parent.opener.drawTop"></frame><frame name="bottomFrame" '+
'src="javascript:parent.opener.drawBottom"><frame></frameset>'
You might also want to check this code is actually being called, maybe the real working popup is loaded from somewhere else by the prev/next buttons and this is just some leftover stuff.
If your onclick function returns false the default browser behaviour is cancelled. As such:
<a href='http://www.google.com' onclick='return check()'>check</a>
<script type='text/javascript'>
function check()
{
return false;
}
This means that you can set your JavaScript function as an onclick event, and just have the anchor tag linking back to the page you are on - as it won't redirect you when you click it but needs a href attribute.

IE 8-9 can't focus to iframe

Hello I getting not visible IFrame in IE I try print it, but IE return error what focus() method not identified. Why I get it? I remember that some days ago it wored
var iFrame = document.frames["printIfram"]; //document.frames.printIframe;
iFrame.focus();
iFrame.print();
Put a print function inside the Iframe to make it print itself on load:
At the bottom of the page, just use window.print()
You missed the e on the end of printIframe.
If that's just a typo, try iFrame.contentWindow.focus().
i got the same problem in ie8 and i thought it's a bug of ie
i tryed the accepted answer ,it haven't work yet;
nomatter where is the window.print(),it always print the parent page
so ,i give up the iframe,just open a new tab to print
have you got it work?

jquery callback after if statement

Howdy guys, im having trouble finding help on creating a callback in certain situations.
I have a piece of code which loads a links page in to an iframe and then changes the scr if another link is pressed.
$(".iframe").hide();
$(".lnk").click(function(){
$(".iframe").show('slow')
;})
;
$(".frmclose").click(function(){
$(".iframe").hide('slow')
;})
;
The above runs within (document).ready
below is outside of this (for some reason it does not work on the inside)
function changeIframeSrc(id, url) {
if (!document.getElementById) return;
var el = document.getElementById(id);
if (el && el.src) {el.src = url;return false;}return true;}
the link :
google
prior to this i have the div in which the iframe is in become unhidden. I also have a button within that div which hides the div + iframe.
What im having problems with is once the iframe has been opened and then closed via the div link if it is re-opened by clicking a different link the iframe unhides to display the old page then changes. But what i want is for the frame to load the new page(while hidden) then unhide to display it. I thought of using a callback after the iframe src change but i cant see where i would implement it.
Example of it happening
(click the GDPH button to see the links for the iframe)
Any thoughts or help appreciated.
Regards
B Stoner
I think that all you need to do is clear the src of the <iframe> when it is closed. That will clear the page so that next time you show the iFrame it will start out blank again.
I made a small demo of this functionality that uses the 3 links from your page as an example. The <iframe> starts hidden (by CSS) and each link will show the <iframe> and then load the remote site. I added a close iframe link to simulate the close link you have under the <iframe> on your site.
Hope this helps!
Edit: Updated the demo link to include the callback part. Somehow missed that when I read the question!
Edit 2: Your changeIframeSrc function was not working was because it was defined inside the jQuery anonymous function and is a closure. See calling Jquery function from javascript
I would catch the .load() event for the iframe, this will fire after the document has been loaded in to the iframe.
$(".iframe").load(function { /* code to run when iframe is loaded */ });

Browser refresh on AJAX with script tags in the response

I'm having some issues with a jQuery AJAX call. My code works fine when I request a page with no javascript in it, but when I have script tags in my code, things start to get weird.
It seems that any script tags referencing external URLs cause the browser to redirect. In firefox, the page goes blank. In safari, the page clears and loads with the content of the AJAX response. In both browsers, the URL doesn't change.
To be specific about my problem; I have a tab control in which I'm trying to embed the walkscore widget. Since it's pretty heavy on the client side, I only want to actually load it once the user clicks the tab it's in. The walkscore AJAX page looks like this:
<script type="text/javascript">
var ws_address = "1 Market St, San Francisco";
var ws_width = "500";
</script>
<script type="text/javascript" src="http://www.walkscore.com/tile/show-tile.php?wsid=MY_WSID">
</script>
Is there some restriction on script tags referencing external sites on AJAX calls? Is there any nice way around this?
-- Edit --
OK I've been playing with it for a bit and have narrowed down the problem a little. Let me try give a better explanation at the same time:
I have two files, index.html and walkscore.html
index.html
function widget() {
var widget = $('#walkscore');
$.get('/walkscore.html', function(data) {
$('#loading').slideUp(function() {
widget.html(data);
loaded[name] = true;
widget.slideDown();
});
});
}
walkscore.html - as shown in the top code block
In index.html, I have a link that calls the widget function. Whenever I click this link, the whole page is replaced by the output of the js file. It happens regardless of the domain the js file is from. It only seems to happen with js files that have document.write in them. It behaves in exactly the same way when I use the $.getScript function, even when it's in index.html
-- Edit --
It seems it has everything to do with the document.write. I made a copy of the walkscore javascript and replaced all occurrences of document.write with jquery.html, and it seems to work properly. I'm (obviously) a js noob. Is this the expected behavior of document.write? How come it doesn't do it when I include the script on a page load?
Load script separately from html content, you can use $.getScript( ).
It has to do with the document.write in the response.. I was able to fix this in Firefox by doing this:
<script type="text/javascript">
// save default document.write function so we can set it back
var write_func_holder = document.write;
// redefine document.write to output text target div
document.write = function(text) {
$('#ad_container').html($('#ad_container').html() + text);
}
</script>
<script language="JavaScript" type="text/javascript" src="javascriptfile">
</script>
<script type="text/javascript">
// reset document.write function
document.write = write_func_holder;
</script>
I'm still getting an issue in Safari where the browser refreshes to a blank page with just the content of the document.write and IE6, IE7 doesn't do anything at all. Firefox works though.
I hope this helps someone figure out what wrong and they in turn can fix the IE6/7 and Safari issues
It happens because of the document.write call. Here's some info on what's going on:
Writing After A Page Has Been Loaded
If document.write() is invoked after a page has finished loading, the entire static (non-script generated) content of a page will be replaced with the write method's parameter. This scenario is most often played out when the write method is invoked from an event handler - whether the method is in a function called by the event handler or alone inside the handler - because event handlers are triggered after a page has finished loading. This is important to know because static content replacement is not always the desired result. Another common scenario for content overwite has to do with writing content to a new window. In this case, the overwrite of blank page is the goal.
(source)
The solution I went with was to eliminate the document.write commands, and replace the content of a div instead. If you're loading an external script, and have no control over it, you can replace the document.write function with your own. It's discussed here:
http://www.webxpertz.net/forums/showthread.php?threadid=11658
Hope that helps someone out there!
Replacing document.write is the way to go. This is shameless self promotion, but if you have a non-trivial case, writeCapture.js handles all the edge cases.
I would first check the response of that script source, maybe something in that causes the unwanted behavior.
I am experiencing the EXACT same behaviour and spent some frustrating hours last night trying to figure out what the problem was and searching for answers to no avail. I'm surprised this is mentioned anywhere in the jquery docs as it seems like a plausible problem not some crazy never-to-be-encountered bug.
Anyway, here's my story in case anyone searches for something related.
I have a jquery enabled page that loads some content into a div using $.ajax(), it all works perfectly. What I needed to do was include one of those twitter retweet buttons that shows a count and enables you to tweet about the content on the page. To do this a simple piece of javascript from them should be included on the page.
<script type="text/javascript" src="http://www.retweet.com/static/retweets.js"></script>
So in theory, that script tag should be returned in the ajax call and jquery should execute it and include the result of it, as I specified the data type as html in the $.ajax() call.
The external script on closer inspection does:
if(!url)
{
var url=window.location.href;
}
if(!size)
var size="big";
var height="75";
var width="54"
if(size=="small")
{
height="22";
width="120";
}
if(!username)
var username="none";
url=url.replace("?", "*");
var src="http://www.retweet.com/widget/button/"+size+"/"+username+"/"+url;
document.write('<iframe src="'+src+'" height="'+height+'" width="'+width+'" frameborder="0" scrolling="no"></iframe>');
Which obviously bombs out on the document.write.
Tonight i'll try the methods in this post and see if they work, thanks for the info.

Categories