Хочу сделать меню с плавной прокруткой при скролле и при нажатии ссылок в меню.
Проблема в том, что при клике на пункт меню предыдущий активный пункт “мигает”.
Предполагаю, что у меня одновременно работают и click, и scroll. И из-за этого такой эффект. Но как запретить одно событие, пока используется другое? Натолкните на мысль, пожалуйста.
Код по ссылке: https://repl.it/repls/SufficientSwiftArraylist
Тут нет простого способа решить задачу нативным API (время скролла не известно, у scrollTo
нет коллбека, в объектах события тоже нет информации что позволит отличить программный скролл от пользовательского в обработчике скролла).
Найди какую-нить простую библиотеку для скроллинга которая поддерживает коллбек когда скролл закончился. Тогда при программном скролле устанавливай флаг, а по завершению программного скролла (для этого и нужен коллбек) убирай флаг. А в обработчике скролла игнорируй все действия если флаг стоит.
Большое спасибо за объяснение. Благодаря ему я смог правильно сформулировать свой вопрос и найти решение.
Вот оно:
let isScrolling = null;
window.addEventListener('scroll', function (evt) {
if (isScrolling !== null) {
clearTimeout(isScrolling);
}
isScrolling = setTimeout(function () {
scrollBehavior(evt);
}, 60);
});
К сожалению, я не совсем понимаю, что здесь происходит и почему в таком виде всё работает, как ожидалось.
Не похоже что этот код будет корректно работать больше 1 раза. Можешь показать работающую демку на repl.it? А я объясню что происходит.
Работает, ссылка та же
Вижу. Суть кода в том что он выполняет scrollBehavior
через 60 миллисекунд как скроллинг закончился (при этом поведение не выполняется если между события скроллинга меньше 60 миллисекунд, а это так когда триггерится программный скроллинг или скроллится большим движением много страницы).
Это разновидность debounce поведения. https://davidwalsh.name/javascript-debounce-function.