JS Функция плавной прокрутки по вертикали и горизонтали

#javascript #html

#javascript #HTML

Вопрос:

Я хочу создать многостраничный мультисайт, где каждый раз, когда нажимается ссылка, она автоматически прокручивается до этого элемента на странице (все элементы div).
Функция работает, но она по-прежнему переходит к заданному элементу.

Вот код, который у меня есть на данный момент, и элементы, которые я использую для вызова функции:

 <li class="topli">
    <a id="toplink" onclick="Scroll('#home')" href="javascript:void(0);">HOME</a>
</li>

<script>
    function Scroll(element) {
        var ID = element.split('#').join('');
        var target = document.getElementById(ID);
        var offset = target.getBoundingClientRect();

        console.log("X:",offset.x,"Y:",offset.y);

        if (window.scrollY != offset.y) {
            window.scroll(window.scrollY, offset.y);
        }

        if (window.scrollX != offset.x) {
            window.scroll(window.scrollX, offset.x);
        }
    }
</script>
  

При необходимости я добавлю более подробный код в JSFiddle.

Комментарии:

1. @Tektiv Это делается в самой функции, если вы посмотрите на первую строку внутри функции, вы увидите, что я использовал функции .split и .join для вычитания # из #home , а затем просто ничего не добавлял..

Ответ №1:

Создайте помощник jQuery для этого

 (function($) {
    $.fn.goTo = function() {
        $('html, body').animate({
            scrollTop: $(this).offset().top   'px'
        }, 'fast');

        return this; 
}
})(jQuery);
  

И использовать, как

 $('#el').goTo();
  

Комментарии:

1. Изначально я хотел сделать это без jQuery, поскольку я еще не очень хорошо знаком с ним, но, учитывая, что вы сказали «помощник», есть ли способ включить jQuery без необходимости включать все каталоги? Также на что .fn. ссылается?

2. .fn — это контракт jQuery на создание виджетов. Итак, да — вы можете вызвать эту функцию в контексте вашего элемента. И вам нужно включить только ссылку на jquery.

3. Хорошо, я все еще пытаюсь сделать это с помощью обычного JS, но я буду иметь это в виду, если это не сработает. Также существует простой эквивалент JS для .animate ? Заранее спасибо..

4. Я пытался сделать это с помощью CSS3, но тоже не могу заставить это работать.. В любом случае спасибо за помощь..

Ответ №2:

Попробуйте это для прокрутки по вертикали (где 100 — скорость прокрутки):

 const goTo = (targetEl) => {
  const elm = document.querySelector(targetEl);
  const offset = elm.getBoundingClientRect().bottom;
  if (offset > window.innerHeight) {
    window.scroll(0, window.scrollY   100);
    setTimeout(() => {
      goTo(targetEl);
    }, 16.666);
  } else {
    return;
  }
};
  

Назовите это так:

 goTo('#scroll-target');
  

или по щелчку:

 window.addEventListener('DOMContentLoaded', () => {
  document.querySelector('.long-div').addEventListener('click', () => {
    goTo('#scroll-target');
  });
});
  

Комментарии:

1. Не могли бы вы объяснить мне, чем этот отличается от моего? Я вижу то же самое, но с другими кодами.. Также что такое const и что () => {..} делает в setTimeout ? Я немного медленно понимаю, что делает JS и почему он это делает, поэтому, если бы вы могли объяснить мне, в чем различия, я был бы очень благодарен!

2. Он обладает аналогичной функциональностью, но теперь является «рекурсивным». По сути, это говорит о прокрутке экрана только на 100 пикселей за раз, если целевой div и страница не выровнены, вызовите функцию снова и делайте это максимум 60 раз в секунду (1000/60). Это дает нам плавную анимацию. Вы также могли бы изучить window.requestAnimationFrame возможность повторного вызова функции.. Что касается const и функции стрелки, взгляните на синтаксис ES6.

3.Не работает, чувак, я получаю ошибки выражения в window.addEventlistener и в setTimeout из const goTo() ..

Ответ №3:

Плавная прокрутка по вертикали, простой и понятный способ:

 let element = document.querySelector('#element');

// Vertical Scroll
this.element.scrollTo({
    left: element.offsetLeft,
    behavior: 'smooth'
})

// Horizontal Scroll
element.scrollIntoView({block: "end", behavior: "smooth"});
  

Документы: