Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.10.2023, 12:37
Новичок на форуме
Отправить личное сообщение для Юра_2310 Посмотреть профиль Найти все сообщения от Юра_2310
 
Регистрация: 20.10.2023
Сообщений: 6

Событие по изменению содержания страницы
Не нашел события, чтобы отследить завершение размещения в DOM изменений на странице в "одностраничном" приложении. То есть при нажатии кнопки функция JS загружает на уже открытую страницу новое содержание. После загрузки надо прокрутить скролл в определенное положение. Если сразу прокрутить (window.scrollTo(0, 6000) или document.documentElement.scrollTop=6000) - выполняет прокрутку примерно на 2/3 от нужной. Небольшие странички работают значительно лучше.
Пробовал подключить событие readystatechange. Но оно не реагирует, т.е. не замечает изменения состояния, всегда "complete". Т.е. загрузка на страницу нового содержания в моем случае не вызывает это событие.
Как решать эту проблему?
Ответить с цитированием
  #2 (permalink)  
Старый 20.10.2023, 12:50
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,730

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

Первый вариант предпочтительнее, второй - при безвыходности.
Ответить с цитированием
  #3 (permalink)  
Старый 20.10.2023, 12:51
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,495

Нет таких событий, потому что все SPA - это просто работа с DOM, никак не связанная с жизненным циклом страницы с точки зрения браузера.

Все SPA фреймворки позволяют тем или иным образом отслеживать отрисовку компонентов в DOM, собственно с этой стороны и надо походить если хотите чистого и правильного кода. Если вы пользуетесь самописной какашкой - то, как и советуют выше, допишите в неё такую возможность.

Если же хотите накостылять, то можно использовать MutationObsrver или\и ResizeObserver для того чтобы следить "снаружи".
__________________
29375, 35
Ответить с цитированием
  #4 (permalink)  
Старый 20.10.2023, 13:08
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,707

После загрузки все изменения в DOM выполняются в одном обработчике, который нельзя прервать какими то событиями. Попробуйте выполнять прокрутку в следующем событии от таймера
setTimeout (() => document.documentElement.scrollTop=6000, 0)

Последний раз редактировалось voraa, 20.10.2023 в 13:15.
Ответить с цитированием
  #5 (permalink)  
Старый 20.10.2023, 15:18
Новичок на форуме
Отправить личное сообщение для Юра_2310 Посмотреть профиль Найти все сообщения от Юра_2310
 
Регистрация: 20.10.2023
Сообщений: 6

Спасибо всем за помощь!
Вариант с setTimeout вполне подошел.
Работает даже задержкой в 1 (о, чудо!): setTimeout(restorePosition, 1);

Правда функцию restorePosition (в которой document.documentElement.scrollTop), сделал асинхронной.
Костыли в виде MutationObsrver или\и ResizeObserver как-то не стал пробовать.

SPA фреймворки - не мое. Импорта замещение (свои какашки) как-то лучше. Просто предпочитаю чистый и правильный код.

Последний раз редактировалось Юра_2310, 20.10.2023 в 15:31.
Ответить с цитированием
  #6 (permalink)  
Старый 20.10.2023, 16:51
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,707

Сообщение от Юра_2310
Правда функцию restorePosition (в которой document.documentElement.scrollTop), сделал асинхронной.
Какой смысл?
Асинхронная отличается от обычной только тем, что в ней можно await использовать и всегда возвращает промис.
Ответить с цитированием
  #7 (permalink)  
Старый 20.10.2023, 17:04
Новичок на форуме
Отправить личное сообщение для Юра_2310 Посмотреть профиль Найти все сообщения от Юра_2310
 
Регистрация: 20.10.2023
Сообщений: 6

Сообщение от voraa Посмотреть сообщение
Какой смысл?
Асинхронная отличается от обычной только тем, что в ней можно await использовать и всегда возвращает промис.
Да, так и написано в учебнике. Еще я слышал, что она работает как бы параллельно, после того как завершится синхронный код. Точно, конечно, не могу сказать.
Но в моем случае не асинхронная - не работает. Только если async.
Еще добавлю, что сама эта асинхронная функция тоже не срабатывала. А вот запуск ее через setTimeout решил проблему. Чудеса, правда?

Последний раз редактировалось Юра_2310, 20.10.2023 в 17:15.
Ответить с цитированием
  #8 (permalink)  
Старый 20.10.2023, 17:24
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,707

В js, кроме worker ничего не работает параллельно, все работает в одном потоке
Сообщение от Юра_2310
Но в моем случае не асинхронная - не работает. Только если async.
Не видя функции ничего нельзя сказать. Если она только вызывается в setTimeout, то ей должно быть абсолютно все равно, объявлена она асинхронной или нет. Весь смыл асинхронной функции, что она вернет промис, который будет разрешен, когда выполнятся какие то асинхронные операции внутри нее. Если там нет асинхронных операций (await), и ничего не возвращает, то она просто вернет Promise.resolve(undefined).

Последний раз редактировалось voraa, 20.10.2023 в 17:27.
Ответить с цитированием
  #9 (permalink)  
Старый 21.10.2023, 04:31
Новичок на форуме
Отправить личное сообщение для Юра_2310 Посмотреть профиль Найти все сообщения от Юра_2310
 
Регистрация: 20.10.2023
Сообщений: 6

Сообщение от voraa Посмотреть сообщение
Не видя функции ничего нельзя сказать.
Вот та функция. Убрал асинхронность. На самом деле работает также. Очевидно, где-то ошибся вначале.

function restorePosition(){
document.documentElement.scrollTop = 6000;
}

Сразу после копирования изменений в DOM:
setTimeout(restorePosition, 0);

Без таймера прокручивает до значения где-то около 4000. Не ожидал такого от таймера. Еще раз спасибо!
Можно ли так сказать, что таймер выдернул функцию из очереди на выполнение и выполнил ее после того как эта очередь освободилась, раз все работает в одном потоке?

Последний раз редактировалось Юра_2310, 21.10.2023 в 11:37.
Ответить с цитированием
  #10 (permalink)  
Старый 21.10.2023, 08:48
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,707

setTimeout ставит функцию в очередь через указанный интервал.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Событие одной страницы перенести на другую страницу dikucher Events/DOM/Window 11 08.02.2014 16:16
Событие загрузки кода страницы Oren2014 Opera, Safari и др. 2 05.12.2013 12:30
Событие onload SP7 Общие вопросы Javascript 4 10.11.2013 23:50
событие на изменение структуры html кода страницы hurt3 jQuery 10 07.07.2013 12:03
Смена содержания страницы без обновления toyo932_st Элементы интерфейса 3 29.11.2010 09:58