Скроллинг при возвращении назад

Знаете одну тайну. Оказывается браузеры запоминают состояние страницы когда переходишь с нее на другую страницу для того чтобы при возвращении назад - они показали то же самое состояние с которого проходил переход. Вы можете проверить это на каком-нибудь старом сайте, перейдя по ссылкам и вернувшись обратно, даже если там были сложные подгрузки.
Но почему то всё стало ломаться когда стали переизобретать стандарты реактивные фреймворки. Да, отлично, придумали keep-alive для того чтобы при возврате восстанавливать все элементы из кеша. Но физически они пропадают из dom структуры, а их скроллинг позиции удаляются вместе с элементами. Недоработки
scrollBehavior помогает только для скроллинга body

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

Помните нашу историю с привязкой ключа keep-alive к нативному ключу истории браузера?

Ой, там не хватает кусочка в котором в качестве key установилась состояние истории браузера

 

key = window.history.state.key

 

Так вот на это хорошо вешается и сохранение состояний прокрутки, нужно лишь слегка допилить код

Поскольку все элементы быстро восстанавливаются из истории - мы можем не заморачиваться с подгрузкой их из запросов

Сразу создадим класс для элементов скроллинг которых нужно сохранять, чтобы не создавать дополнительную нагрузку там где это не надо. Пусто будет .horizontal-scroller

Добавим место хранения наших скроллеров в компонент содержащий keep-alive

data(){
return {

key: window.history.state.key
scrollers: {},

}
}

И добавим геттер и сеттер для сохранения и установки позиций всех скроллеров при изменении истории. Этого более чем достаточно

watch: {
$route() {
this.scrollers[this.key] = [
...document.querySelectorAll(".horizontal-scroller"),
].map(index => index.scrollLeft)
this.key = window.history.state.key
this.$nextTick(() => {
if (this.scrollers[this.key]) {
document
.querySelectorAll(".horizontal-scroller")
.forEach((e, key) => (e.scrollLeft = this.scrollers[this.key][key]))
}
})
},
},

 

Надеюсь, помог вам сделать веб лучше. Удачи

  • Автор: kosmom
  • Рейтинг: 0
  • Просмотров: 737
  • Комментариев: 0
  • Создан: 20.09.2021 12:32

Комментарии (0)