views:

229

answers:

4

Hi Experts, (excuse me if this is not the right forum to post - i couldn't find anything related to non-native programming and related to this topic)

I Am trying to set a dynamic HTML into an iFrame on the webpage. I have tried a couple of things but none of them seem to work. I m able to read the innerHTML but can't seem to update it.

// Able to read using 
document.getElementById('iFrameIdentifier').innerHTML;

// On Desktop IE, this code works 
document.getElementById('iFrameId').contentWindow.document.open();
document.getElementById('iFrameId').contentWindow.document.write(dynamicHTML);
document.getElementById('iFrameId').contentWindow.document.close();

Ideally the same function should work as how it works for div's but it says 'Object doesn't support this method or property".

I have also tried document.getElementById('iFrameId').document.body.innerHTML.

This apparently replaces the whole HTML of the page and not just the innerHTML.

I have tried out a couple of things and they didn't work

  • document.getElementById('iFrameId').body.innerHTML
  • document.frames[0].document.body.innerHTML

My purpose is to have a container element which can contain dynamic HTML that's set to it.

I've been using it well till now when I observed that the setting innerHTML on a div is taking increasing amount of time because of the onClicks or other JS methods that are attached to the anchors and images in the dynamic HTML. Appears the JS methods or the HTML is some how not getting cleaned up properly (memory leak?)

Also being discussed - http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_26185526.html#a32779090

A: 

I have tried a couple of things but none of them seem to work.

Welcome to IEMobile! Nothing you know about DOM scripting applies here.

Unfortunately, cross-iframe scripting does not appear to be possible in IEMobile6-7.

  • frameelement.contentDocument (the standard DOM method) isn't available
  • frameelement.contentWindow.document (the IE6-7 workaround version) isn't available
  • the old-school Netscape window.frames array only works for frames, not iframes
  • having the child document pass up its document object to the window.parent only works for frames, not iframes. In an iframe, window.parent===window.

So the only ways forward I can see are:

  1. use frames instead of iframes. Nasty. Or,
  2. use document.cookie to communicate between parent and child: the child document is just a script, that checks for a particular cookie in document.cookie on a poller, and when it's found that's a message from the parent, and it can write some HTML or whatever. Slow and nasty. Or,
  3. using the server-side to inject content into the frames, passing it in as an argument to a script. Slow, nasty, and potentially insecure. Or,
  4. avoid frames completely (best, if you can). Or,
  5. drop support from IEMobile6-7 (best for preserving your sanity, if you can get away with it!)

Appears the JS methods or the HTML is some how not getting cleaned up properly (memory leak?)

Yes, probably. IEMobile6-7(*) is close to unusable at dynamic HTML. It gives you a lovely flavour of what scripting used to be like for us poor gits back in the Netscape 4 days.

Try to avoid creating and destroying lots of nodes and event handlers. Keep the page as static as possible, re-using element nodes where possible and setting text node data properties in preference to tearing everything down and making anew with createElement or innerHTML. Use an event stub (onclick="return this._onclick()") in the HTML together with writing to _onclick if you need to set event handlers from JavaScript, in preference to recreating the HTML with a new event handler (or just trying to set the property, which of course doesn't work in IEMobile). Avoid long-running single pages when you can.

It'll still crash, but hopefully it'll take longer.

*: that is, the versions of IE present on WinMo before version 6.1.4, where it became the infinitely better IEMobile8, marketed as “Internet Explorer Mobile 6” (thank you Microsoft).

bobince
What I'm saying is that you can't write event handler properties from JavaScript in IEMobile, ie., `document.getElementById('x').onclick= somefunction`. The only way you can attach to `click` events is by using an actual inline event handler in the HTML, like `<a onclick="return somefunction();">`. This is normally dreadful practice, to be avoided, and it means you can't change the event handler without recreating the HTML (and hence leaking memory). Using a stub `onclick` attribute that just forwards to an `_onclick` property, which you *can* write from JavaScript, avoids the problem.
bobince
I understand the stub implementation now. But I am replacing the whole HTML (dynamic) each time and not just the onClick() attributes. I like the idea though that using stubs we can clear the stub implementations there by clearing out the memory used by the JS implementations kinda like disconnecting a pointer right ?But one of the primary reasons for me to stick to dynamic HTML on a same page was to avoid reloading the Javascripts each time. I have the JS implementations loaded once and the dynamic HTML uses it many times.
A: 
Yeah, sorry, I think you're right... I was thinking about frames. For *i*frames even the small amount of stuff that works with frames is no-go. Updated answer with some alternatives.
bobince
A: 

@bobince - I read your possible alternatives.

use frames instead of iframes. Nasty. Or,

I'd prefer to use iFrames as they give the flexibility of a container on IE Mobile.

use document.cookie to communicate between parent and child: the child document is just a script, that checks for a particular cookie in document.cookie on a poller, and when it's found that's a message from the parent, and it can write some HTML or whatever. Slow and nasty. Or,

This does sound nasty for a simple cause.

using the server-side to inject content into the frames, passing it in as an argument to a script. Slow, nasty, and potentially insecure. Or,

I am a device side only application. No server/AJAXy requests for I/O.

avoid frames completely (best, if you can). Or,

I wish i could, but to avoid the memory leak because of innerHTML. I started to look out for iFrames first.

drop support from IEMobile6-7 (best for preserving your sanity, if you can get away with it!)

Unfortunately this isn't in my scope. My app has to target the specified browser.

I did start with Approach#2 as explained below as it seems that's the only way out. I am facing 2 problems at the moment

  • The iFrame's src attribute isn't able to refer to a .html file other than at the root of the phone's directory - Sad.

  • I am unable to call a parent Javascript from inside the iFrame's javascript. Any clue ? I have already tried parent.example() or top.example(). This doesn't even seem to work on Desktop IE8. It works on Mozilla Firefox though.

p.s - excuse me for using the answer section for posting/updating information. The comments appears to have a text size limitation.

Okay, my bad - the parent.someFunction() works on IE8 and FF. It isn't on IEMobile only. But any other way to?
http://stackoverflow.com/questions/623208/access-parents-dom-from-script-in-an-iframe-in-ie-mobileSeems we can't access a parent's DOM or its Javascripts on IEMobile. It is one obsolete browser. :(
Got rid of both the problems. ------------------------------------------------ I was giving the path to the file using '\' instead of '/'. I know so dumb. ------------------------------------------------ This I've explained in the solution to the problem. Not the best of the ideas - but still worked.
A: 

Okay, I kinda resolved the issues that i was facing earlier and the bigger issue which was setting HTML to an iFrame on IEMobile. But i still have one more PIA which is related to double scollbars - which i am currently looking into. There seems to be more poor souls facing similar problem - if i fix that too. I will post an update here.

How did i finally write to iFrame on IEMobile? Have 2 divs one to wrap the iFrame and the other to write inside an iFrame.

document.getElementById('OuterDiv').innerHTML = '';
document.getElementById('OuterDiv').innerHTML = '<iframe id="iFrameId" src="somefile.html"></iframe>';

This creates an iFrame each time and in the somefile.html on load there is a InnerDiv.innerHTML which doesn't seem to leak the memory.

In the somefile.html there will be an onLoad method which will fetch the HTML (explained below on how i managed to get it) and do a

document.getElementById('InnerDiv').innerHTML = dynamicHTML;

How did I manage to pass the HTML between parent and child iFrame As well explained by @bobince earlier, one has to rely on 3rd party service like a cookie or a server to pass around the data between parent and the child iFrame.

I infact used an ActiveXControl to set and get data from the parent and child iFrame's javascript respectively. I won't recommend doing this if you have to introduce an ActiveX Control just for this. I accidentally already have one which I use to get the Dynamic HTML in the first place.

If you need any help you can DM me - Twitter @Swaroop

Thanks @bobince for your help. I am marking this one as an answer because it says what i did to fix the issue.