2008-09-15 6 views
0

ich einen Web-Seite Code zu entwickeln, die dynamisch den Inhalt vom Server abruft und dann legt diesen Inhalt Container-Knoten mit so etwas wieinnerHTML- Manipulation in JavaScript

container.innerHTML = content; 

Manchmal muß ich einigen vorherigen Inhalt überschrieben werden in dieser Knoten. Dies funktioniert gut, bis es passiert, dass der vorherige Inhalt mehr vertikalen Platz belegte, als ein neuer Platz belegte UND ein Benutzer die Seite herunterscrollte - mehr scrollte als neuer Inhalt erlaubte, vorausgesetzt seine Höhe.

In diesem Fall wird die Seite falsch neu gezeichnet - einige Artefakte des alten Inhalts bleiben erhalten. Es funktioniert gut und es ist sogar möglich, Artefakte zu beseitigen, indem man den Browser minimiert und wiederherstellt (oder das Fenster zwingt, auf andere Weise neu gezeichnet zu werden), aber das scheint nicht sehr praktisch zu sein.

Ich teste dies nur unter Safari (das ist eine iPhone-optimierte Website).

Hat jemand die Idee, wie man damit umgeht?

+0

Tritt dies in allen Browsern oder bestimmten Browsern auf? – EndangeredMassa

+0

Ich interessiere mich nur für Safari (das ist iPhone-optimierte Website), also testet nur in diesem. –

Antwort

4

Die einfachste Lösung, die ich gefunden habe, würde einen Anker-Tag <a> an der Spitze der div Sie bearbeiten, zu platzieren sein:

<a name="ajax-div"></a> 

Dann, wenn Sie den Inhalt der div ändern, können Sie dies tun den Browser Sprung zu Ihrem Anker-Tag haben:

location.hash = 'ajax-div'; 

verwendet der Benutzer sicherstellen, dass viel zu nicht nach unten gescrollt, wenn Sie die Inhalte aktualisieren und Sie sollen das Problem nicht in erster Linie bekommen.

(getestet in der neuesten FF-Beta und der letzten Safari)

0

Es klingt, als ob Sie ein Problem mit dem Browser selbst haben. Tritt dieses Problem nur in einem Browser auf?

Eine Sache, die Sie versuchen könnten, ist eine leichte Bibliothek wie jQuery. Es behandelt Browser Unterschiede ziemlich gut. So stellen Sie den inneren HTML für ein div mit der ID Container Sie würden es einfach schreiben:

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

die in den meisten Browsern funktionieren. Ich weiß nicht, ob es Ihr Problem spezifisch beheben wird oder nicht, aber es kann einen Versuch wert sein.

0

Würde es funktionieren, die Bildlaufposition wieder an den Anfang zu setzen (element.scrollTop = 0; element.scrollLeft = 0; auswendig), bevor der Inhalt ersetzt wird?

1

Es klingt wie die Webkit-Rendering-Engine von Safari erkennt die Inhaltsänderung zunächst nicht, zumindest nicht vollständig genug, um den vorherigen HTML-Inhalt zu entfernen. Durch das Minimieren und anschließende Wiederherstellen der Fenster wird ein Redraw-Ereignis in der Rendering-Engine des Browsers ausgelöst.

Ich denke, ich würde 2 Avenues erkunden: erstens könnte ich einen iframe anstelle des aktuellen "Content" -Knoten verwenden? Browser erwarten, dass sich IFrames ändern, aber wie Sie sehen, sind sie nicht immer so gut darin, den Inhalt von DIV oder anderen Elementen zu ändern.

Zweitens, vielleicht durch Ändern der Bildlaufposition wie zuvor vorgeschlagen. Sie können die Rolle einfach wie vorgeschlagen auf 0 zurückstellen, oder wenn das zu aufdringlich ist, könnten Sie versuchen, den Bildlauf nach der Inhaltsänderung wiederherzustellen. Subtrahieren Sie die Höhe des alten Inhaltsknotens von der aktuellen Bildlaufposition (indem Sie den Bildlauf des Browsers auf die 0 des Inhaltsknotens zurücksetzen), ändern Sie den Knoteninhalt, und fügen Sie dann die Höhe des neuen Knotens zur Bildlaufposition hinzu.

Palehorse hat zwar Recht (ich kann seine Antwort im Moment nicht stimmen - keine Punkte) eine Abstraktionsbibliothek wie jQuery, Dojo oder sogar Prototype kann oft mit diesen Fragen helfen. Besonders wenn Sie sehen, dass Ihre Seite/Site sich über die einfache DOM-Manipulation hinaus bewegt, werden Sie die Tools und Erweiterungen von Bibliotheken als große Hilfe finden.

0

Legen Sie die CSS-Höhe des Elements bei jeder Aktualisierung von innerHTML auf 'auto' fest.

0

Ich würde versuchen, container.innerHTML = ''; Container.innerHTML = Inhalt;