Как изменить параметр для плавной прокрутки экрана
Написал код для плавной прокрутки экрана, но не могу теперь найти способ немного его подправить. Дело в том, что при прокрутке меню налазит на заголовок секции https://yadi.sk/i/IU_N_JHC3aVxQC
А хотелось бы вот так: https://yadi.sk/i/Md3-S5su3aVxUm //Передача в переменную всех элементов html на странице let elements = document.documentElement, body = document.body,//Передаем в переменную body links = document.links;//Получаем все якорные ссылки на странице //Функция опредления нажатой ссылки и расчета перемещения function calcScroll() { //Перебор циклом все ссылок и определение той, на которой был сделан клик for (let i = 0; i < links.length; i++) { links[i].onclick = function() { //Определение и округление текущего расстояния от верха документа let scrollTop = Math.round(body.scrollTop || elements.scrollTop); if (this.hash !== '') { //Предотвращение действия браузера по дефолту при отсутвии атрибута hash у элемента event.preventDefault(); //Получение элемента, к которому ведет якорь нажатой ссылки let hashElement = document.getElementById(this.hash.substring(1)), hashElementTop = 0; //Вычисление через цикл расстояния от верха до элемента, к которому ведет нажатая ссылка while (hashElement.offsetParent) { hashElementTop += hashElement.offsetTop; hashElement = hashElement.offsetParent; } //Получение округленного значения расположения элемента hashElementTop = Math.round(hashElementTop); /* Функция запуска плавного перемещения (содержит аргументы: текущее растояние от верха документа, расстояние от верха документа к контентному блоку, к которому ведет нажатая ссылка и сам контентный блок) */ smoothScroll(scrollTop, hashElementTop, this.hash); } }; } }; calcScroll(); let timeInterval = 1, //Задаем временной интервал в 1 миллисекунду prevScrollTop, speed; //Функция плавной прокрутки function smoothScroll(from, to, hash) { /* Если элемент (конечная точка движения) расположен ниже текущей точки экрана, то scroll ведется с верху вниз (положительное значение), если наоборот, то снизу вверх (отрицательное значение) */ if (to > from) { speed = 10; } else { speed = -10; } //Установка интервала движения let move = setInterval(function() { //Получение и округение текущей позиции экрана scrollTop = Math.round(body.scrollTop || elements.scrollTop); //Условия прекращения или продолжения движения if ( prevScrollTop === scrollTop || (to > from && scrollTop >= to) || (to < from && scrollTop <= to) ) { clearInterval(move); //Добавление атрибута hash в url после прокрутки (добавляется к адресной строке в браузере) window.location.hash = hash; } else { body.scrollTop += speed; elements.scrollTop += speed; /* Передача текущей позиции экрана в переменную, которая при последующих перемещениях будет играть роль места хранения последней позиции экрана */ prevScrollTop = scrollTop; } }, timeInterval);//Передача ранее установленного интервала перемещения } |
DVV,
сделайте минимальный макет |
|
|
Через такое пробовал. Ничего вообще не работает
document.querySelector("элемент на который нажимать").onclick = document.querySelector("элемент к которому крутить").scrollIntoView({behavior: 'smooth'}); |
DVV,
строка 63 Цитата:
history.pushState строка 19 hashElementTop = 0; сделать hashElementTop = -80; |
DVV,
строка 11 добавить event function(event) |
DVV,
и того ... //Плавная прокрутка //Передача в переменную всех элементов html на странице let elements = document.documentElement, body = document.body,//Передаем в переменную body links = document.links;//Получаем все якорные ссылки на странице //Функция опредления нажатой ссылки и расчета перемещения function calcScroll() { //Перебор циклом все ссылок и определение той, на которой был сделан клик for (let i = 0; i < links.length; i++) { links[i].onclick = function(event) { //Определение и округление текущего расстояния от верха документа let scrollTop = Math.round(body.scrollTop || elements.scrollTop); if (this.hash !== '') { //Предотвращение действия браузера по дефолту при отсутвии атрибута hash у элемента event.preventDefault(); //Получение элемента, к которому ведет якорь нажатой ссылки let hashElement = document.getElementById(this.hash.substring(1)), hashElementTop = -80; //Вычисление через цикл расстояния от верха до элемента, к которому ведет нажатая ссылка while (hashElement.offsetParent) { hashElementTop += hashElement.offsetTop; hashElement = hashElement.offsetParent; } //Получение округленного значения расположения элемента hashElementTop = Math.round(hashElementTop); /* Функция запуска плавного перемещения (содержит аргументы: текущее растояние от верха документа, расстояние от верха документа к контентному блоку, к которому ведет нажатая ссылка и сам контентный блок) */ smoothScroll(scrollTop, hashElementTop, this.hash); } }; } }; calcScroll(); let timeInterval = 1, //Задаем временной интервал в 1 миллисекунду prevScrollTop, speed; //Функция плавной прокрутки function smoothScroll(from, to, hash) { /* Если элемент (конечная точка движения) расположен ниже текущей точки экрана, то scroll ведется с верху вниз (положительное значение), если наоборот, то снизу вверх (отрицательное значение) */ if (to > from) { speed = 10; } else { speed = -10; } //Установка интервала движения let move = setInterval(function() { //Получение и округение текущей позиции экрана scrollTop = Math.round(body.scrollTop || elements.scrollTop); //Условия прекращения или продолжения движения if ( prevScrollTop === scrollTop || (to > from && scrollTop >= to) || (to < from && scrollTop <= to) ) { clearInterval(move); //Добавление атрибута hash в url после прокрутки (добавляется к адресной строке в браузере) history.pushState(history.state, document.title, location.href.replace(/#.*$/g, '') + hash); } else { body.scrollTop += speed; elements.scrollTop += speed; /* Передача текущей позиции экрана в переменную, которая при последующих перемещениях будет играть роль места хранения последней позиции экрана */ prevScrollTop = scrollTop; } }, timeInterval);//Передача ранее установленного интервала перемещения } |
Большое спасибо)) Вот если бы оно еще и в IE11 работало:dance:
|
DVV,
скопируйте код выше снова. исправлена ошибка в строке 68. |
Цитата:
это работает!!! проблема в другом скрипте |
Цитата:
return '0' + num; |
Это я уже понял. Перевел на ES5. Теперь в IE все работает, но заметил глюк какой-то. Если кликнуть на одном пункте меню, а затем сразу на другом, пока еще экран крутится, то экран улетает или в самый низ или верх, после чего на последующие клики на пункты меню уже не реагирует пока не обновить страницу или не пошевелить экран колесом мышки((
Аналогичный глюк происходит, если кликнуть на первом пункте меню, а затем когда экран остановится, еще раз на нем. |
DVV,
.... clearInterval(move); smoothScroll(scrollTop, hashElementTop, this.hash); .... let move; function smoothScroll(from, to, hash) { .... //Установка интервала движения |
DVV,
так на всякий случай, setInterval лучше никогда не использовать, но дело ваше. альтернатива setInterval – рекурсивный setTimeout как делать анимацию js-animation |
Спасибо)) Теперь намного лучше. За исключением последнего глюка все отлично работает. Я знаю, что тут лучше requestAnimationFrame использовать, но я ее еще только изучаю и пока научился пользоваться только для простеньких анимаций.
|
Часовой пояс GMT +3, время: 09:57. |