jquery анимация прокрутки всей страницы - PullRequest
0 голосов
/ 06 февраля 2020

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

$.fn.isInViewport = function() {
  var elementTop = $(this).offset().top;
  var elementBottom = elementTop + $(this).outerHeight();

  var viewportTop = $(window).scrollTop();
  var viewportBottom = viewportTop + $(window).height();

  return elementBottom > viewportTop && elementTop < viewportBottom;
};

let sections = $(".scroll-dest");
let lastSt = 0;
let running = false;

$(window).scroll(event => {
  if(!running) {
    running = true
  event.preventDefault();
  let current = null;

  sections.each((i, v) => {
    if ($(v).isInViewport()) current = i;
  });

  let st = $(this).scrollTop();
  if (st > lastSt) {
    // console.log("down");
    console.log(current != sections.length - 1)
    if (current != sections.length - 1) {
      $("html").animate(
        {
          scrollTop: $(sections[current + 1]).offset().top
        },
        500
      );
    }
  } else {
    // console.log("up");
    if (current > 0) {
      $("html").animate(
        {
          scrollTop: $(sections[current - 1]).offset().top
        },
        500
      );
    }
  }
  lastSt = st;
  running = false
}
});

Также , сценарий должен прокрутить до раздела, который находится до или после текущего раздела. Но это прокрутка по всей длине страницы, а это не то, что я хочу.

1 Ответ

0 голосов
/ 06 февраля 2020

Не используйте событие прокрутки для этого, попробуйте использовать API наблюдателя пересечения (IO) для этого. Он был создан для решения подобных проблем, для реагирования, когда элементы становятся видимыми или пересекаются друг с другом в области просмотра.

Сначала вы определите параметры для ввода-вывода:

let options = {
  rootMargin: '0px',
  threshold: 1.0
}

После того, как параметры определены, вы говорите, какие элементы вы хотите наблюдать:

const elements = document.querySelectorAll('.scroll-dest');

Как На последнем шаге вы должны определить, что произойдет, когда элемент появится в поле зрения, и привязать его к определенным вами элементам:

const intersectionObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {

    // when element's is in viewport,
    // do something with it!
    if (entry.intersectionRatio > 0) {
      animate(entry.target);
      // remove observer after animation (if it is no longer needed). 
      // remove this line if you want to continue observing this element.
      observer.unobserve(entry.target); 
    }
  });
});
elements.forEach((element) => intersectionObserver.observe(element));

Если вам требуется поддержка старых браузеров, чем использовать этот (официальный) polyfill из w3 c, он воссоздает наблюдателя пересечения с прослушиванием событий прокрутки. Так что он будет работать медленнее в старых браузерах, с этим ничего не поделаешь. Но на более новых будет увеличение производительности.

Вы также можете подумать об использовании window.scrollTo () вместо jQuery animate для повышения производительности.

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