Как определить, когда прокрутка начинает использовать Javascript / Jquery? - PullRequest
1 голос
/ 02 марта 2020

Я хочу создать одностраничный веб-сайт без использования сторонних библиотек, таких как FullPage. js.

  • при запуске прокрутки -> вместо ожидания окончания естественного конца прокрутка, я хочу, чтобы она не имела никакого эффекта (поэтому никакой видимой прокрутки, вызванной мышью) и вместо этого запускала мой код. (так что всегда можно go перейти к следующему или предыдущему разделу, не полагаясь на количество прокрутки пользователей)

У вас есть идеи, как мне этого добиться? Мой фрагмент кода ожидает окончания прокрутки и затем переходит туда, где и должен, поэтому он не работает должным образом.

(первый раздел имеет класс current, а затем фрагмент кода работает путем манипулирования 100vh разделов, добавив / удалив этот класс)

Вы можете увидеть фрагмент кода, который я использую ниже или здесь: https://codepen.io/makiwara/pen/PoqjdNZ

Большое спасибо за вашу помощь , хорошего дня!

var script = document.createElement('script');script.src = "https://code.jquery.com/jquery-3.4.1.min.js";document.getElementsByTagName('head')[0].appendChild(script);
var timerId;
var scrollableElement = document.body; //document.getElementById('scrollableElement');

scrollableElement.addEventListener('wheel', checkScrollDirection);

function checkScrollDirection(event) {
    var $current = $('.current');
  if (checkScrollDirectionIsUp(event)) {
    console.log('UP');
$prev = $current.prev();

            if ($prev.length) {

                clearTimeout(timerId);
                timerId = setTimeout(function(){
                    $current.removeClass('current');
                    $prev.addClass('current');    
                    $('body,html').animate({
                        scrollTop: $('.current').offset().top
                    }, 100);         
                }, 100) 
            }




  } else {
    console.log('Down');
$next = $current.next();

            if ($next.length) {
                clearTimeout(timerId);
                timerId = setTimeout(function(){
                    $current.removeClass('current');
                    $next.addClass('current');
                    $('body,html').animate({
                        scrollTop: $('.current').offset().top
                    }, 100);         
               } , 100) 
            }

  }
}

function checkScrollDirectionIsUp(event) {
  if (event.wheelDelta) {
    return event.wheelDelta > 0;
  }
  return event.deltaY < 0;
}

1 Ответ

1 голос
/ 02 марта 2020

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

То, что делает ваш код, по сути устраняет неполадки т.е. ограничивает вызов функции только по истечении периода ожидания.

Сначала откажитесь от используемых вами таймеров. Вам нужно как-то заблокировать прокрутку, чтобы она не повторялась. Часть JavaScript может быть легкой, если вы используете Underscore. js функция газа с одним предупреждением: она проходит через последующие события после истечения периода времени. К счастью, его метод debouncing принимает третий аргумент, который задает поведение, которое вам нужно:

scrollableElement.addEventListener(
  "wheel",
  _.debounce(checkScrollDirection, 200, true) // immediately call the function _once_
);

Этот третий аргумент заставляет debounce-функцию вести себя как удушенная, то есть она будет запускать только один раз и в то же время он сразу же запустит .

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

function checkScrollDirection(event) {
  var $current = $(".current");
  if (checkScrollDirectionIsUp(event)) {
    console.log("UP");
    $prev = $current.prev("section");
    if ($prev.length) {
      $current.removeClass("current");
      $prev.addClass("current");
      $("body,html").animate(
        {
          scrollTop: $prev.offset().top
        },
        100
      );
    }
  } else {
    console.log("Down");
    $next = $current.next("section");
    if ($next.length) {
      $current.removeClass("current");
      $next.addClass("current");
      $("body,html").animate(
        {
          scrollTop: $next.offset().top
        },
        100
      );
    }
  }
}

btw, попробуйте чтобы привыкнуть указывать селекторы внутри .next() и .prev(), поскольку jQuery будет соответствовать всем возможным родным братьям, что, скорее всего, вам не нужно. В этом случае codepen добавляет дополнительные <script> элементы, и jQuery также будет соответствовать им.

Теперь, если вы попробуете это, вы заметите, что окно по-прежнему реагирует на каждые событие прокрутки. События прокрутки - это одно из тех событий, которые нельзя отменить, поэтому необходимо отключить их с помощью CSS

Самый простой способ - скрыть переполнение body

body { max-height: 100vh; overflow: hidden; }

И это оно. Вам может потребоваться настроить период ожидания газа в соответствии с вашими предпочтениями.

Рабочую версию кодового ручки можно найти здесь: https://codepen.io/vassiliskrikonis/pen/XWbgxLj

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...