window.scrollTo с setTimeout входит в бесконечный цикл, но работает нормально без setTimeout - PullRequest
2 голосов
/ 14 мая 2019

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

while(document.documentElement.scrollTop <= document.body.scrollHeight-500){
     window.scrollTo(0, document.documentElement.scrollTop+500);
}

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

while (document.documentElement.scrollTop <= document.body.scrollHeight - 500) {
setTimeout(
    function() {
        window.scrollTo(0, document.documentElement.scrollTop + 500);
    }, 300);
}

Теперь это заканчивается бесконечным циклом, я полагаю, из-за асинхронностикак-то выпрыгивает из времени.

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

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

setTimeout(func, n) очередей func для вызова (как минимум) n мс.

, поэтому ваш второй подход в основном

while (document.documentElement.scrollTop <= document.body.scrollHeight - 500) {
  addAnotherTimeout();
}

Кодвнутри цикла не влияет на состояние цикла, поэтому здесь вы получаете бесконечный цикл.

Здесь рекурсивная версия (вид):

var scrollTimeout;
function scrollElement(){
    clearTimeout(scrollTimeout);
    if(document.documentElement.scrollTop <= document.body.scrollHeight-500){
        window.scrollTo(0, document.documentElement.scrollTop+500);
        scrollTimeout = setTimeout(scrollElement, 300);
    }
}

// start the scrolling:
scrollElement();

Часть сclearTimeout() в начале scrollElement() не требуется для самого цикла / рекурсии, но для предотвращения нескольких одновременных циклов.

Если вы запускаете второй цикл, а предыдущий еще не закончен,убить предыдущего.

1 голос
/ 14 мая 2019

Один из вариантов - поместить его в функцию async и await Обещание, которое разрешается через 300 мс внутри while:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
(async () => {
  while (document.documentElement.scrollTop <= document.body.scrollHeight - 500) {
    window.scrollTo(0, document.documentElement.scrollTop + 500);
    await delay(300);
  }
})();
...