Вопрос

Я разрабатываю код веб-страницы, который динамически извлекает содержимое с сервера, а затем помещает это содержимое в узлы контейнера, используя что-то вроде

container.innerHTML = content;

Иногда мне приходится перезаписывать некоторое предыдущее содержимое в этом узле.Это работает нормально, пока не случится так, что предыдущий контент занимал больше места по вертикали, чем занимал бы новый, И пользователь прокрутил страницу вниз - прокрутил больше, чем позволил бы новый контент, при условии его высоты.

В этом случае страница перерисовывается неправильно - сохраняются некоторые артефакты старого содержимого.Это работает нормально, и даже можно избавиться от артефактов, свернув и восстановив браузер (или принудительно перерисовать окно другим способом), однако это кажется не очень удобным.

Я тестирую это только в Safari (это веб-сайт, оптимизированный для iPhone).

У кого-нибудь есть идея, как с этим справиться?

Это было полезно?

Решение

Самым простым решением, которое я нашел, было бы разместить тег привязки <a> в верхней части div вы редактируете:

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

Затем, когда вы измените содержимое div, вы можете сделать это , чтобы браузер перешел к вашему тегу привязки.:

location.hash = 'ajax-div';

Используйте это, чтобы убедиться, что пользователь не прокручивается слишком далеко вниз при обновлении содержимого, и вы не должны столкнуться с проблемой в первую очередь.

(протестировано в последней бета-версии FF и последней версии safari)

Другие советы

Похоже, что механизм рендеринга webkit в Safari сначала не распознает изменение содержимого, по крайней мере, недостаточно полно, чтобы удалить предыдущее содержимое html.Сворачивание, а затем восстановление Windows инициирует событие перерисовки в механизме рендеринга браузера.

Я думаю, что я бы исследовал 2 пути:во-первых, могу ли я использовать iframe вместо текущего узла "content"?Браузеры ожидают, что IFrames изменятся, однако, как вы видите, они не всегда так хороши в изменении содержимого DIV или других элементов.

Во-вторых, возможно, изменив положение прокрутки, как было предложено ранее.Вы могли бы просто переместить прокрутку обратно в 0, как предложено, или, если это слишком навязчиво, вы могли бы попытаться восстановить прокрутку после изменения содержимого.Вычтите высоту старого узла содержимого из текущей позиции прокрутки (сбросив значение прокрутки браузера до 0 для узла содержимого), измените содержимое узла, затем добавьте высоту нового узла к позиции прокрутки.

Хотя Пейлхорс прав (на данный момент я не могу проголосовать за его ответ - нет баллов), библиотека абстракций, такая как jQuery, Dojo или даже Prototype, часто может помочь в этих вопросах.Особенно, если вы видите, что ваша страница / сайт выходит за рамки простых манипуляций с DOM, вы обнаружите, что инструменты и усовершенствования, предоставляемые библиотеками, окажут вам огромную помощь.

Похоже, у вас возникла проблема с самим браузером.Возникает ли эта проблема только в одном браузере?

Одна вещь, которую вы могли бы попробовать, - это использовать облегченную библиотеку, такую как jQuery.Он довольно хорошо справляется с различиями в браузерах.Чтобы установить внутренний HTML-код для div с идентификатором контейнер вы бы просто написали это:

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

Это будет работать в большинстве браузеров.Я не знаю, решит ли это конкретно вашу проблему или нет, но, возможно, стоит попробовать.

Сработает ли установка положения прокрутки обратно в верхнее положение (element.scrollTop = 0;элемент.scrollLeft = 0;наизусть) перед заменой содержимого?

Устанавливайте высоту CSS элемента в значение "auto" каждый раз, когда вы обновляете innerHTML.

Я бы попробовал сделать container.innerHTML = ";container.innerHTML = содержимое;

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top