Как прокрутить страницу HTML до заданного якоря?


264

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

Я указал nameили idатрибут в моем HTML-коде:

 <a name="anchorName">..</a>

или

 <h1 id="anchorName2">..</h1>

Я хотел бы получить тот же эффект, что и вы, перейдя к http://server.com/path#anchorName. Страница должна быть прокручена так, чтобы якорь находился в верхней части видимой части страницы.

Ответы:


349
function scrollTo(hash) {
    location.hash = "#" + hash;
}

JQuery не требуется вообще!


92
Это на самом деле не прокручивать, а просто прыгает. В этот момент вы могли бы просто сослаться на якорь<a href="#anchorName">link</a>
Райан

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

13
Вы не должны использовать scrollTo, потому что он уже используется объектом глобального окна. Также параметр не должен называться hash, потому что location.hash тоже определен. Вы можете использовать этот код:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Маркус Зеллер

3
@MarkusZeller, почему параметр не должен называться хешем? Это не сталкивается с местоположением, не так ли?
Герман

3
это делает прокрутку, если вы установите "scroll-поведения: smooth;" на элемент html
укладчики

225

Намного проще:

var element_to_scroll_to = document.getElementById('anchorName2');
// Or:
var element_to_scroll_to = document.querySelectorAll('.my-element-class')[0];
// Or:
var element_to_scroll_to = $('.my-element-class')[0];
// Basically `element_to_scroll_to` just have to be a reference
// to any DOM element present on the page
// Then:
element_to_scroll_to.scrollIntoView();

22
Сначала я думал, что Мандкс троллинг, затем я попробовал это, и это сработало. Помимо меня, как я никогда не сталкивался с этим методом раньше. Mozilla Docs для этого метода . Кроме того, похоже, что это будет очень хорошо поддерживаться в браузерах.
Джонатан Думайн

2
У меня было много проблем с решениями jquery, не прокручивая. Это спасло меня от многих разочарований.
NuclearPeon

1
ПРЕДУПРЕЖДЕНИЕ! Этот метод может иметь проблемы, если div выше него содержит плавающие элементы и не может легко определить его размер.
vogomatix

5
Это чистое решение, однако на данный момент оно не допускает каких-либо настроек, оно выполняет жесткую прокрутку. Существует экспериментальный параметр, scrollIntoViewOptionsкоторый имеет behavior: "smooth"опцию, но в настоящее время он совместим только с Firefox.
Роча

Как оживить это?
SkuraZZ

124

Вы можете использовать jQuerys .animate () , .offset () и scrollTop. подобно

$(document.body).animate({
    'scrollTop':   $('#anchorName2').offset().top
}, 2000);

пример ссылки: http://jsbin.com/unasi3/edit

Если вы не хотите анимировать, используйте .scrollTop () как

$(document.body).scrollTop($('#anchorName2').offset().top);

или яваскрипты родные location.hashкак

location.hash = '#' + anchorid;

1
Что касается создания селектора для поиска <h1 id="anchorName">или <a name="anchorName">, используйте $('#'+hash+',a[name='+hash+']')или слегка оптимизируйте его, $(document.getElementById(hash) || 'a[name='+hash+']')который будет сначала искать элемент по идентификатору и прибегать к поиску только в том случае, если он не найден.
Gnarf

@gnarf - Нет необходимости оптимизировать селекторы '#' в jQuery - они уже оптимизированы для вас. Это довольно легко увидеть, если вы прочитали исходный код jQuery.
CodeJoust

3
@CodeJoust - я работаю в команде jQuery, я много раз ее читал, и да $("#selector")оптимизирован, но $("#selector,a[name='selector']")не будет проходить те же оптимизации так же быстро. Полагаю, мой 2,5-летний комментарий звучит немного странно. «Оптимизация» избегает a[name='selector']поиска, если он находит идентификатор, а не оптимизирует поиск по идентификатору.
gnarf

1
Мне немного повезло с таким подходом: <a data-hash="about"> About </a> <script> $ ("[data-hash]"). Click (function () {var data = $ (this) .attr ("data-hash"); $ (document.body) .animate ({'scrollTop': $ ("#" + data) .offset (). top}, 500);}); </ script>
Джаззи

33

Отличное решение от jAndy, но при плавной прокрутке возникают проблемы с работой в Firefox.

Написание этого способа работает и в Firefox.

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);

В последнем выпуске Chrome это единственный найденный мной метод, который постоянно работает. Спасибо за чаевые!
Габори

32

2018-2020 Pure JS:

Существует очень удобный способ прокрутки до элемента:

el.scrollIntoView({
  behavior: 'smooth', // smooth scroll
  block: 'start' // the upper border of the element will be aligned at the top of the visible part of the window of the scrollable area.
})

Но, насколько я понимаю, он не имеет такой хорошей поддержки, как варианты ниже.

введите описание изображения здесь

Узнайте больше о методе.


Если необходимо, чтобы элемент находился сверху:

const element = document.querySelector('#element')
const topPos = element.getBoundingClientRect().top + window.pageYOffset

window.scrollTo({
  top: topPos, // scroll so that the element is at the top of the view
  behavior: 'smooth' // smooth scroll
})

Демонстрационный пример на Codepen


Если вы хотите, чтобы элемент находился в центре:

const element = document.querySelector('#element')
const rect = element.getBoundingClientRect() // get rects(width, height, top, etc)
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.scroll({
  top: rect.top + rect.height / 2 - viewHeight / 2,
  behavior: 'smooth' // smooth scroll
});

Демонстрационный пример на Codepen


Служба поддержки:

введите сюда изображение

Они пишут, что scrollэто тот же метод scrollTo, но поддержка показывает лучше в scrollTo.

Подробнее о методе


Это решение работает очень, очень хорошо! Спасибо, что поделился!
gaborous

29

Чистое решение JavaScript без JQuery. Проверено на Chrome & Ie, не проверено на IOS

function ScrollTo(name) {
  ScrollToResolver(document.getElementById(name));
}

function ScrollToResolver(elem) {
  var jump = parseInt(elem.getBoundingClientRect().top * .2);
  document.body.scrollTop += jump;
  document.documentElement.scrollTop += jump;
  if (!elem.lastjump || elem.lastjump > Math.abs(jump)) {
    elem.lastjump = Math.abs(jump);
    setTimeout(function() { ScrollToResolver(elem);}, "100");
  } else {
    elem.lastjump = null;
  }
}

демо: https://jsfiddle.net/jd7q25hg/12/


1
Извиняюсь за комментирование старой темы, но это работает лучше всего для меня, так как мой проект не использует JQuery. Единственная проблема, которую я заметил, это то, что она пропускает 5 пикселей или около того, если вы прокрутите до самого верха.
AntBirch

Очень приятно видеть чистую версию JS. Я учу студентов всегда заглядывать под капот и понимать, что делает для них JQuery, так что это хороший пример.
Дейв Эверитт

2
Это должен быть принятый ответ: это чистый пример JS И он достигает желаемого эффекта анимации прокрутки. Я установил значение тайм-аута до 20, и оно работает безупречно.
Марк Баррассо

Спасибо, я люблю чистые решения javascript
R01010010

2
Работает в IOS, только что проверил.
Дебби Курт

23

В 2018 году вам не нужен jQuery для чего-то простого. Встроенный scrollIntoView()метод поддерживает behaviorсвойство " " для плавной прокрутки к любому элементу на странице. Вы даже можете обновить URL браузера с помощью хэша, чтобы сделать его доступным для закладки.

Из этого урока по прокрутке HTML-закладок можно родным способом автоматически добавить плавную прокрутку ко всем ссылкам на вашей странице:

let anchorlinks = document.querySelectorAll('a[href^="#"]')
 
for (let item of anchorlinks) { // relitere 
    item.addEventListener('click', (e)=> {
        let hashval = item.getAttribute('href')
        let target = document.querySelector(hashval)
        target.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        })
        history.pushState(null, null, hashval)
        e.preventDefault()
    })
}

2
Отличный ответ, который устраняет зависимость от jQuery
zai chang

Вот Это Да! Работает потрясающе!
Александру Трандафир Каталин

14

Плавно прокрутите до нужной позиции (2019)

Получить правильную y координату и использоватьwindow.scrollTo({top: y, behavior: 'smooth'})

const id = 'anchorName2';
const yourElement = document.getElementById(id);
const y = yourElement.getBoundingClientRect().top + window.pageYOffset;

window.scrollTo({top: y, behavior: 'smooth'});

Со смещением

scrollIntoViewэто тоже хороший вариант, но в некоторых случаях он может не работать идеально. Например, когда вам нужно дополнительное смещение . С scrollToвами просто нужно добавить , что смещение , как это:

const yOffset = -10; 

window.scrollTo({top: y + yOffset, behavior: 'smooth'});

Я думаю, что вы должны добавить следующее в файл стиля CSS: css html { scroll-behavior: smooth; }
parismiguel

5
$(document).ready ->
  $("a[href^='#']").click ->
    $(document.body).animate
      scrollTop: $($(this).attr("href")).offset().top, 1000

5

Решение от CSS-Tricks больше не работает в jQuery 2.2.0. Это вызовет ошибку селектора:

Ошибка выполнения JavaScript: синтаксическая ошибка, нераспознанное выражение: a [href * = #]: нет ([href = #])

Я исправил это, изменив селектор. Полный фрагмент этого:

$(function() {
  $("a[href*='#']:not([href='#'])").click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
    var target = $(this.hash);
    target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
    if (target.length) {
      $('html,body').animate({
        scrollTop: target.offset().top
      }, 1000);
      return false;
    }
  }
 });
});

4

Большинство ответов излишне сложны.

Если вы просто хотите перейти к целевому элементу, вам не нужен JavaScript:

# the link:
<a href="#target">Click here to jump.</a>

# target element:
<div id="target">Any kind of element.</div>

Если вы хотите анимировать прокрутку к цели , обратитесь к ответу @ Shahil.


Иногда вам нужно делать это динамически, хотя; т.е. без прямого действия пользователя. Я верю, что этого хочет ОП.
jpaugh

1
Да, ОП явно знал о функциональности якорной ссылки.
Ишервуд

4

Это работает:

$('.scroll').on("click", function(e) {

  e.preventDefault();

  var dest = $(this).attr("href");

  $("html, body").animate({

    'scrollTop':   $(dest).offset().top

  }, 2000);

});

https://jsfiddle.net/68pnkfgd/

Просто добавьте класс «прокрутка» к любым ссылкам, которые вы хотите анимировать


Хорошее, простое в использовании решение. Спасибо!
Смитти-Вербен-Ягер-Мандженсон

3

Это рабочий скрипт, который прокрутит страницу до якоря. Для настройки просто присвойте ссылке привязки идентификатор, соответствующий атрибуту имени привязки, на которую вы хотите перейти.

<script>
jQuery(document).ready(function ($){ 
 $('a').click(function (){ 
  var id = $(this).attr('id');
  console.log(id);
  if ( id == 'cet' || id == 'protein' ) {
   $('html, body').animate({ scrollTop: $('[name="' + id + '"]').offset().top}, 'slow'); 
  }
 }); 
});
</script>

2

Я знаю, что это действительно старый вопрос, но я нашел простое и простое решение jQuery в css-tricks . Это тот, который я использую сейчас.

$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});

1
Селектор выбрасывает исключение в jquery 2.2.0. 0x800a139e - Ошибка времени выполнения JavaScript: синтаксическая ошибка, нераспознанное выражение: a [href * = #]: нет ([href = #])
Билл Шихара


2

решение vue2 ... добавить простое свойство данных, чтобы просто принудительно обновить

  const app = new Vue({ 
  ... 

  , updated: function() {
           this.$nextTick(function() {
           var uri = window.location.href
           var anchor = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
           if ( String(anchor).length > 0 && this.updater === 'page_load' ) {
              this.updater = "" // only on page-load !
              location.href = "#"+String(anchor)
           }
         })
        }
     });
     app.updater = "page_load"

 /* smooth scrolling in css - works in html5 only */
 html, body {
     scroll-behavior: smooth;
 }

0

Самый простой способ заставить браузер прокручивать страницу до заданной привязки - это ввести свой style.css * {scroll-поведения: smooth;} и в своей html-навигации использовать #NameOfTheSection

*{scroll-behavior: smooth;}
<a href="#scroll-to">Home<a/>

<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>

<section id="scroll-to">
<p>it will scroll down to this section</p>
</section>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.