20.10.2023, 12:37
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 6
|
|
Событие по изменению содержания страницы
Не нашел события, чтобы отследить завершение размещения в DOM изменений на странице в "одностраничном" приложении. То есть при нажатии кнопки функция JS загружает на уже открытую страницу новое содержание. После загрузки надо прокрутить скролл в определенное положение. Если сразу прокрутить (window.scrollTo(0, 6000) или document.documentElement.scrollTop=6000) - выполняет прокрутку примерно на 2/3 от нужной. Небольшие странички работают значительно лучше.
Пробовал подключить событие readystatechange. Но оно не реагирует, т.е. не замечает изменения состояния, всегда "complete". Т.е. загрузка на страницу нового содержания в моем случае не вызывает это событие.
Как решать эту проблему?
|
|
20.10.2023, 12:50
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Изменить скрипт, который модифицирует содержимое страницы таким образом, чтобы он генерировал событие в конце своего "жизненного процесса", либо повесить на страницу MutationObserver и слушать все изменения на странице до тех пор, пока они не прекратятся на какое-то время.
Первый вариант предпочтительнее, второй - при безвыходности.
|
|
20.10.2023, 12:51
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,587
|
|
Нет таких событий, потому что все SPA - это просто работа с DOM, никак не связанная с жизненным циклом страницы с точки зрения браузера.
Все SPA фреймворки позволяют тем или иным образом отслеживать отрисовку компонентов в DOM, собственно с этой стороны и надо походить если хотите чистого и правильного кода. Если вы пользуетесь самописной какашкой - то, как и советуют выше, допишите в неё такую возможность.
Если же хотите накостылять, то можно использовать MutationObsrver или\и ResizeObserver для того чтобы следить "снаружи".
__________________
29375, 35
|
|
20.10.2023, 13:08
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,748
|
|
После загрузки все изменения в DOM выполняются в одном обработчике, который нельзя прервать какими то событиями. Попробуйте выполнять прокрутку в следующем событии от таймера
setTimeout (() => document.documentElement.scrollTop=6000, 0)
Последний раз редактировалось voraa, 20.10.2023 в 13:15.
|
|
20.10.2023, 15:18
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 6
|
|
Спасибо всем за помощь!
Вариант с setTimeout вполне подошел.
Работает даже задержкой в 1 (о, чудо!): setTimeout(restorePosition, 1);
Правда функцию restorePosition (в которой document.documentElement.scrollTop), сделал асинхронной.
Костыли в виде MutationObsrver или\и ResizeObserver как-то не стал пробовать.
SPA фреймворки - не мое. Импорта замещение (свои какашки) как-то лучше. Просто предпочитаю чистый и правильный код.
Последний раз редактировалось Юра_2310, 20.10.2023 в 15:31.
|
|
20.10.2023, 16:51
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,748
|
|
Сообщение от Юра_2310
|
Правда функцию restorePosition (в которой document.documentElement.scrollTop), сделал асинхронной.
|
Какой смысл?
Асинхронная отличается от обычной только тем, что в ней можно await использовать и всегда возвращает промис.
|
|
20.10.2023, 17:04
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 6
|
|
Сообщение от voraa
|
Какой смысл?
Асинхронная отличается от обычной только тем, что в ней можно await использовать и всегда возвращает промис.
|
Да, так и написано в учебнике. Еще я слышал, что она работает как бы параллельно, после того как завершится синхронный код. Точно, конечно, не могу сказать.
Но в моем случае не асинхронная - не работает. Только если async.
Еще добавлю, что сама эта асинхронная функция тоже не срабатывала. А вот запуск ее через setTimeout решил проблему. Чудеса, правда?
Последний раз редактировалось Юра_2310, 20.10.2023 в 17:15.
|
|
20.10.2023, 17:24
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,748
|
|
В js, кроме worker ничего не работает параллельно, все работает в одном потоке
Сообщение от Юра_2310
|
Но в моем случае не асинхронная - не работает. Только если async.
|
Не видя функции ничего нельзя сказать. Если она только вызывается в setTimeout, то ей должно быть абсолютно все равно, объявлена она асинхронной или нет. Весь смыл асинхронной функции, что она вернет промис, который будет разрешен, когда выполнятся какие то асинхронные операции внутри нее. Если там нет асинхронных операций (await), и ничего не возвращает, то она просто вернет Promise.resolve(undefined).
Последний раз редактировалось voraa, 20.10.2023 в 17:27.
|
|
21.10.2023, 04:31
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 6
|
|
Сообщение от voraa
|
Не видя функции ничего нельзя сказать.
|
Вот та функция. Убрал асинхронность. На самом деле работает также. Очевидно, где-то ошибся вначале.
function restorePosition(){
document.documentElement.scrollTop = 6000;
}
Сразу после копирования изменений в DOM:
setTimeout(restorePosition, 0);
Без таймера прокручивает до значения где-то около 4000. Не ожидал такого от таймера. Еще раз спасибо!
Можно ли так сказать, что таймер выдернул функцию из очереди на выполнение и выполнил ее после того как эта очередь освободилась, раз все работает в одном потоке?
Последний раз редактировалось Юра_2310, 21.10.2023 в 11:37.
|
|
21.10.2023, 08:48
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,748
|
|
setTimeout ставит функцию в очередь через указанный интервал.
|
|
|
|