Як прокрутити HTML-сторінку до заданого якоря?


264

Я хотів би зробити так, щоб браузер прокручував сторінку до заданого якоря, просто за допомогою JavaScript.

Я вказав a nameабо idатрибут у своєму коді HTML:

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

або

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

Я хотів би отримати той самий ефект, який ви отримаєте, перейшовши на сторінку http://server.com/path#anchorName. Сторінку слід прокручувати так, щоб якор знаходився біля верхньої частини видимої частини сторінки.

Відповіді:


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

Жодного jQuery не потрібно!


91
Це насправді не прокручується, але просто стрибає. У цей момент ви також можете просто посилання на якір<a href="#anchorName">link</a>
Райан

52
Зауважте, що це спрацює лише один раз. Після встановлення хеша сторінка не буде прокручуватися до того самого хеша, якщо ви не зміните його на манекен, а потім встановіть його знову.
Крістіан Врабе

13
Не слід використовувати scrollTo, оскільки він вже використовується об'єктом глобального вікна. Також параметр не повинен бути названий хеш, тому що також визначено location.hash. Ви можете використовувати цей код:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Маркус Зеллер

3
@MarkusZeller, чому параметр не повинен називатися хеш? Це не стикається з місцеположенням, чи не так?
Герман

3
це робиться прокрутка, якщо встановлено "поведінка прокрутки: гладка;" на 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.
rocha

Як це оживити?
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);

або javascripts рідний 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"> Про </a> <script> $ ("[хеш даних]"). Click (function () {var data = $ (this) .attr ("хеш даних"); $ (document.body) .animate ({'scrollTop': $ ("#" + data). offset (). top}, 500);}); </script>
Джазі

32

Чудове рішення jAndy, але, як видається, у плавного прокручування виникають проблеми, що працюють у Firefox.

Написавши це таким чином, працює і в Firefox.

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

В останньому випуску Chrome це єдиний метод, який я знайшов, який постійно працює. Дякую за пораду!
габоровий

32

2018-2020 чисті 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 .

Детальніше про метод


Це рішення працює дуже добре! Дякую, що поділились!
габоровий

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 * = #]: not ([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/

Просто додайте клас «прокрутка» до будь-яких посилань, які ви хочете анімувати


Приємне, просте у використанні рішення. Дякую!
Smitty-Werben-Jager-Manjenson

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-трюках . Це я зараз використовую.

$(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 * = #]: not ([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-поведінка: гладкий;}, а в 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.