Событие по изменению содержания страницы
Не нашел события, чтобы отследить завершение размещения в DOM изменений на странице в "одностраничном" приложении. То есть при нажатии кнопки функция JS загружает на уже открытую страницу новое содержание. После загрузки надо прокрутить скролл в определенное положение. Если сразу прокрутить (window.scrollTo(0, 6000) или document.documentElement.scrollTop=6000) - выполняет прокрутку примерно на 2/3 от нужной. Небольшие странички работают значительно лучше.
Пробовал подключить событие readystatechange. Но оно не реагирует, т.е. не замечает изменения состояния, всегда "complete". Т.е. загрузка на страницу нового содержания в моем случае не вызывает это событие. Как решать эту проблему? |
Изменить скрипт, который модифицирует содержимое страницы таким образом, чтобы он генерировал событие в конце своего "жизненного процесса", либо повесить на страницу MutationObserver и слушать все изменения на странице до тех пор, пока они не прекратятся на какое-то время.
Первый вариант предпочтительнее, второй - при безвыходности. |
Нет таких событий, потому что все SPA - это просто работа с DOM, никак не связанная с жизненным циклом страницы с точки зрения браузера.
Все SPA фреймворки позволяют тем или иным образом отслеживать отрисовку компонентов в DOM, собственно с этой стороны и надо походить если хотите чистого и правильного кода. Если вы пользуетесь самописной какашкой - то, как и советуют выше, допишите в неё такую возможность. Если же хотите накостылять, то можно использовать MutationObsrver или\и ResizeObserver для того чтобы следить "снаружи". |
После загрузки все изменения в DOM выполняются в одном обработчике, который нельзя прервать какими то событиями. Попробуйте выполнять прокрутку в следующем событии от таймера
setTimeout (() => document.documentElement.scrollTop=6000, 0) |
Спасибо всем за помощь!
Вариант с setTimeout вполне подошел. Работает даже задержкой в 1 (о, чудо!): setTimeout(restorePosition, 1); Правда функцию restorePosition (в которой document.documentElement.scrollTop), сделал асинхронной. Костыли в виде MutationObsrver или\и ResizeObserver как-то не стал пробовать. SPA фреймворки - не мое. Импорта замещение (свои какашки) как-то лучше. Просто предпочитаю чистый и правильный код. |
Цитата:
Асинхронная отличается от обычной только тем, что в ней можно await использовать и всегда возвращает промис. |
Цитата:
Но в моем случае не асинхронная - не работает. Только если async. Еще добавлю, что сама эта асинхронная функция тоже не срабатывала. А вот запуск ее через setTimeout решил проблему. Чудеса, правда? |
В js, кроме worker ничего не работает параллельно, все работает в одном потоке
Цитата:
|
Цитата:
function restorePosition(){ document.documentElement.scrollTop = 6000; } Сразу после копирования изменений в DOM: setTimeout(restorePosition, 0); Без таймера прокручивает до значения где-то около 4000. Не ожидал такого от таймера. Еще раз спасибо! Можно ли так сказать, что таймер выдернул функцию из очереди на выполнение и выполнил ее после того как эта очередь освободилась, раз все работает в одном потоке? |
setTimeout ставит функцию в очередь через указанный интервал.
|
Исправил интервал у таймера, как вы предлагали сразу (на 0).
Цитата:
Но по факту таймер позволяет выполнить загрузку страницы до конца. Я и саму страницу увеличил в размерах в два раза. Все равно она успевает загрузиться до выполнением таймером указанной функции. Таймер не выдерживает интервал 0. Почему так происходит? Разве нет противоречия с вашим утверждением? |
Таймер ставит функцию в очередь через указанный промежуток времени. В конец очереди. Но сейчас выполняется ваша функция. После нее уже могут стоять другие задачи - например какие нибудь обработчики событий от мыши. Плюс к тому же между задачами из очереди в соответствии с частотой экрана делается рендерин страницы, который может потребовать перерасчета стилей И только когда все это выполнится, будет выполняться функция, заданная таймером.
Реально это не выполнить функцию через указанный промежуток, а поставить в очередь. |
Цитата:
Теперь понятно. Вроде бы вы это и написали. Особенно "В конец очереди" для меня прояснило ситуацию. |
Часовой пояс GMT +3, время: 02:35. |