Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как изменить параметр для плавной прокрутки экрана (https://javascript.ru/forum/dom-window/74988-kak-izmenit-parametr-dlya-plavnojj-prokrutki-ehkrana.html)

DVV 23.08.2018 17:43

Как изменить параметр для плавной прокрутки экрана
 
Написал код для плавной прокрутки экрана, но не могу теперь найти способ немного его подправить. Дело в том, что при прокрутке меню налазит на заголовок секции 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);//Передача ранее установленного интервала перемещения
}

рони 23.08.2018 19:02

DVV,
сделайте минимальный макет

рони 23.08.2018 19:08

DVV,
http://javascript.ru/forum/misc/7401...ehlementu.html

DVV 23.08.2018 19:15

https://cdn.rawgit.com/ViacheslavDem...c75/index.html

DVV 23.08.2018 19:24

Через такое пробовал. Ничего вообще не работает
document.querySelector("элемент на который нажимать").onclick = document.querySelector("элемент к которому крутить").scrollIntoView({behavior: 'smooth'});

рони 23.08.2018 19:42

DVV,
строка 63
Цитата:

Сообщение от DVV
window.location.hash = hash;

переделать на
history.pushState
строка 19
hashElementTop = 0;
сделать
hashElementTop = -80;

рони 23.08.2018 19:55

DVV,
строка 11 добавить event
function(event)

рони 23.08.2018 19:57

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);//Передача ранее установленного интервала перемещения
}

DVV 23.08.2018 20:38

Большое спасибо)) Вот если бы оно еще и в IE11 работало:dance:

рони 23.08.2018 20:54

DVV,
скопируйте код выше снова. исправлена ошибка в строке 68.

рони 23.08.2018 21:06

Цитата:

Сообщение от DVV
Вот если бы оно еще и в IE11 работало

//Плавная прокрутка
это работает!!!
проблема в другом скрипте

рони 23.08.2018 21:14

Цитата:

Сообщение от DVV
Вот если бы оно еще и в IE11 работало

return `0${num}`;

return '0' + num;

DVV 26.08.2018 17:56

Это я уже понял. Перевел на ES5. Теперь в IE все работает, но заметил глюк какой-то. Если кликнуть на одном пункте меню, а затем сразу на другом, пока еще экран крутится, то экран улетает или в самый низ или верх, после чего на последующие клики на пункты меню уже не реагирует пока не обновить страницу или не пошевелить экран колесом мышки((
Аналогичный глюк происходит, если кликнуть на первом пункте меню, а затем когда экран остановится, еще раз на нем.

рони 26.08.2018 18:14

DVV,
....
clearInterval(move);
smoothScroll(scrollTop, hashElementTop, this.hash);

....
let move;
function smoothScroll(from, to, hash) {
....
//Установка интервала движения
let move = setInterval(function() {

рони 26.08.2018 18:20

DVV,
так на всякий случай, setInterval лучше никогда не использовать, но дело ваше.
альтернатива setInterval – рекурсивный setTimeout

как делать анимацию
js-animation

DVV 26.08.2018 18:35

Спасибо)) Теперь намного лучше. За исключением последнего глюка все отлично работает. Я знаю, что тут лучше requestAnimationFrame использовать, но я ее еще только изучаю и пока научился пользоваться только для простеньких анимаций.


Часовой пояс GMT +3, время: 09:57.