views:

1496

answers:

6

I am developing a web page code, which fetches dynamically the content from the server and then places this content to container nodes using something like

container.innerHTML = content;

Sometimes I have to overwrite some previous content in this node. This works fine, until it happens that previous content occupied more vertical space then a new one would occupy AND a user scrolled the page down -- scrolled more than new content would allow, provided its height.

In this case the page redraws incorrectly -- some artifacts of the old content remain. It works fine, and it is even possible to get rid of artifacts, by minimizing and restoring the browser (or force the window to be redrawn in an other way), however this does not seem very convenient.

I am testing this only under Safari (this is a iPhone-optimized website).

Does anybody have the idea how to deal with this?

A: 

It sounds like you are having a problem with the browser itself. Does this problem only occur in one browser?

One thing you might try is using a lightweight library like jQuery. It handles browser differences fairly nicely. To set the inner HTML for a div with the ID of container you would simply write this:

$('#container').html( content );

That will work in most browsers. I do not know if it will fix your problem specifically or not but it may be worth a try.

palehorse
A: 

Would it work to set the scroll position back to the top (element.scrollTop = 0; element.scrollLeft = 0; by heart) before replacing the content?

Twan
+1  A: 

It sounds like the webkit rendering engine of Safari is not at first recognizing the content change, at least not fully enough to remove the previous html content. Minimizing and then restoring the windows initiates a redraw event in the browser's rendering engine.

I think I would explore 2 avenues: first could I use an iframe instead of the current 'content' node? Browsers expect IFrames to change, however as you're seeing they're not always so good at changing content of DIV or other elements.

Secondly, perhaps by modifying the scroll position as suggested earlier. You could simply move the scroll back to 0 as suggested or if that is to obtrusive you could try to restore the scroll after the content change. Subtract the height of the old content node from the current scroll position (reseting the browser's scroll to the content node's 0), change the node content, then add the new node's height to the scroll position.

Palehorse is right though (I can't vote his answer up at the moment - no points) an abstraction library like jQuery, Dojo, or even Prototype can often help with these matters. Especially if you see your page / site moving beyond simple DOM manipulation you'll find the tools and enhancements provided by libraries to be a huge help.

jpbarto
A: 

Set the element's CSS height to 'auto' every time you update innerHTML.

Thevs
A: 

I would try doing container.innerHTML = ''; container.innerHTML = content;

Vitaly Sharovatov
+3  A: 

The easiest solution I have found would be to place an anchor tag at the top of the div you are editing:

< a name="ajax-div" />

Then when you change the content of the div, you can do this to have the browser jump to your anchor tag:

location.hash = 'ajax-div';

Use this to make sure the user isnt scrolled down too far when you update the content and you shouldn't get the issue in the first place.

(tested in the latest FF beta and latest safari)

Scott S.