Bagaimana cara menggulir halaman HTML ke jangkar yang diberikan?

264

Saya ingin membuat browser untuk menggulir halaman ke jangkar yang diberikan, hanya dengan menggunakan JavaScript.

Saya telah ditentukan nameatau idatribut dalam kode HTML saya:

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

atau

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

Saya ingin mendapatkan efek yang sama dengan yang Anda dapatkan dengan menavigasi ke http://server.com/path#anchorName. Halaman tersebut harus digulir sehingga jangkar berada di dekat bagian atas halaman yang terlihat.

Juha Syrjälä
sumber

Jawaban:

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

Tidak diperlukan jQuery sama sekali!

Dean Harding
sumber
92
Itu tidak benar-benar gulir, itu hanya melompat. Pada titik itu Anda mungkin juga hanya tautan ke jangkar<a href="#anchorName">link</a>
Ryan
52
Perhatikan bahwa ini hanya akan berfungsi sekali. Setelah hash diatur, halaman tidak akan menggulir ke hash yang sama kecuali jika Anda mengubahnya menjadi dummy lalu mengaturnya lagi.
Cristian Vrabie
13
Anda tidak boleh menggunakan scrollTo, karena sudah digunakan oleh objek jendela global. Juga parameter tidak boleh dinamai hash, karena location.hash didefinisikan juga. Anda dapat menggunakan kode ini:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Markus Zeller
3
@ MarkusZeller, mengapa parameter tidak boleh disebut hash? Itu tidak bertabrakan dengan lokasi, bukan?
Gherman
3
ini akan menggulir jika Anda mengatur "scroll-behaviour: smooth;" pada elemen html
stackers
225

Cara yang lebih sederhana:

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();
Armando Pérez Marqués
sumber
22
Mula-mula saya mengira Mandx trolling, lalu saya coba ini dan berhasil. Di luar saya bagaimana saya tidak pernah menemukan metode ini sebelumnya. Mozilla Docs untuk metode ini . Juga, tampaknya ini akan didukung dengan sangat baik di browser.
Jonathan Dumaine
2
Saya punya banyak masalah dengan solusi jquery yang tidak bergulir. Ini menyelamatkan saya dari banyak frustrasi.
NuclearPeon
1
PERINGATAN! Metode ini dapat memiliki masalah jika div di atasnya mengandung elemen mengambang dan tidak dapat menentukan ukurannya dengan mudah.
vogomatix
5
Ini adalah solusi bersih, namun sampai sekarang tidak memungkinkan tweaker, itu memang gulir keras. Ada parameter eksperimental scrollIntoViewOptionsyang memiliki behavior: "smooth"opsi, tetapi saat ini hanya kompatibel dengan Firefox.
rocha
Bagaimana cara menghidupkan ini?
SkuraZZ
124

Anda dapat menggunakan jQuerys .animate () , .offset () dan scrollTop. Suka

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

contoh tautan: http://jsbin.com/unasi3/edit

Jika Anda tidak ingin menghidupkan gunakan .scrollTop () suka

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

atau javascripts asli location.hashsuka

location.hash = '#' + anchorid;
jandy
sumber
1
Sejauh membuat pemilih untuk menemukan <h1 id="anchorName">atau <a name="anchorName">, gunakan $('#'+hash+',a[name='+hash+']')atau sedikit dioptimalkan $(document.getElementById(hash) || 'a[name='+hash+']')yang akan mencari elemen dengan id terlebih dahulu, dan menggunakan pencarian hanya jika ada yang tidak ditemukan.
gnarf
@gnarf - Tidak perlu mengoptimalkan pemilih '#' di jQuery - mereka sudah dioptimalkan untuk Anda. Cukup mudah untuk melihat apakah Anda telah membaca kode sumber jQuery.
CodeJoust
3
@CodeJoust - Saya di tim jQuery, saya sudah membacanya berkali-kali, dan ya $("#selector")dioptimalkan tetapi $("#selector,a[name='selector']")tidak akan melalui optimasi yang sama dengan cepat. Saya kira komentar saya yang berumur 2,5 tahun sedikit terdengar aneh. "Optimasi" menghindari a[name='selector']pencarian jika ia menemukan id, tidak mengoptimalkan pencarian id.
gnarf
1
Saya beruntung dengan pendekatan ini: <a data-hash="about"> Tentang </a> <script> $ ("[data-hash]"). Klik (fungsi () {var data = $ (ini) .attr ("data-hash"); $ (document.body) .animate ({'scrollTop': $ ("#" + data) .offset (). top}, 500);}); </script>
Jazzy
33

Solusi hebat oleh jAndy, tetapi gulir yang mulus tampaknya mengalami masalah saat bekerja di firefox.

Menulisnya dengan cara ini juga berfungsi di Firefox.

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);
5 jamL
sumber
Dalam rilis Chrome terbaru ini adalah satu-satunya metode yang saya temukan yang secara konsisten berfungsi. Terima kasih atas tipnya!
Gaborous
32

2018-2020 Murni js:

Ada cara yang sangat mudah untuk menggulir ke elemen:

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.
})

Tetapi sejauh yang saya mengerti dia tidak memiliki dukungan yang baik seperti opsi di bawah ini.

masukkan deskripsi gambar di sini

Pelajari lebih lanjut tentang metode ini.


Jika perlu, elemen ada di atas:

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
})

Contoh demonstrasi pada Codepen


Jika Anda ingin elemen berada di tengah:

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
});

Contoh demonstrasi pada Codepen


Dukung:

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

Mereka menulis itu scrolladalah metode yang sama scrollTo, tetapi dukungan menunjukkan lebih baik scrollTo.

Lebih lanjut tentang metode ini

Илья Зеленько
sumber
Solusi ini bekerja dengan sangat baik! Terima kasih telah berbagi!
Gaborous
29

Solusi javascript murni tanpa JQuery. Diuji pada Chrome & Ie, tidak diuji pada 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;
  }
}

demo: https://jsfiddle.net/jd7q25hg/12/

Michael Whinfrey
sumber
1
Permintaan maaf untuk mengomentari topik lama tapi ini bekerja paling baik untuk saya karena proyek saya tidak menggunakan JQuery. Satu-satunya masalah yang saya perhatikan adalah bahwa ia kehilangan 5 piksel atau lebih jika Anda menggulir ke bagian paling atas.
AntBirch
Sangat menyegarkan untuk melihat versi js murni. Saya mengajar siswa untuk selalu melihat di bawah tenda dan memahami apa yang JQuery lakukan untuk mereka, jadi ini adalah contoh yang bagus.
Dave Everitt
2
Ini harus menjadi jawaban yang diterima: ini adalah contoh js murni DAN itu mencapai efek animasi bergulir yang diinginkan. Saya menyesuaikan nilai batas waktu menjadi 20 dan berfungsi dengan sempurna.
Mark Barrasso
Terima kasih, saya suka solusi javascript murni
R01010010
2
Bekerja di iOS baru saja mengujinya.
Debbie Kurth
23

Pada 2018, Anda tidak perlu jQuery untuk hal sederhana seperti ini. Dibangun di scrollIntoView()Metode mendukung "behavior " properti untuk lancar gulir ke setiap elemen pada halaman. Anda bahkan dapat memperbarui URL peramban dengan hash agar dapat dibookmark.

Dari tutorial tentang cara menggulir Penanda HTML , berikut adalah cara asli untuk menambahkan pengguliran yang lancar ke semua tautan jangkar pada halaman Anda secara otomatis:

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()
    })
}
kepulan coco
sumber
2
Jawaban luar biasa yang menghilangkan ketergantungan pada jQuery
zai chang
Wow! Bekerja luar biasa!
Alexandru Trandafir Catalin
14

Gulir dengan lancar ke posisi yang tepat (2019)

Dapatkan koordinat yang benar y dan gunakanwindow.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'});

Dengan offset

scrollIntoViewjuga merupakan pilihan yang baik tetapi dalam beberapa kasus mungkin tidak berfungsi dengan baik. Misalnya saat Anda membutuhkan tambahan offset . Dengan scrollToAnda hanya perlu menambahkan offset itu seperti ini:

const yOffset = -10; 

window.scrollTo({top: y + yOffset, behavior: 'smooth'});
Arseniy-II
sumber
Saya pikir Anda harus menambahkan yang berikut ini ke file gaya CSS: css html { scroll-behavior: smooth; }
parismiguel
5
$(document).ready ->
  $("a[href^='#']").click ->
    $(document.body).animate
      scrollTop: $($(this).attr("href")).offset().top, 1000
kaktus
sumber
5

Solusi dari CSS-Trik tidak lagi berfungsi di jQuery 2.2.0. Ini akan menimbulkan kesalahan pemilih:

JavaScript runtime error: Kesalahan sintaksis, ekspresi tidak dikenal: a [href * = #]: tidak ([href = #])

Saya memperbaikinya dengan mengubah pemilih. Cuplikan lengkapnya adalah ini:

$(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;
    }
  }
 });
});
Bill Shihara
sumber
4

Sebagian besar jawaban tidak perlu rumit.

Jika Anda hanya ingin melompat ke elemen target, Anda tidak perlu JavaScript:

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

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

Jika Anda ingin menggulir ke target dengan animasi , silakan merujuk ke jawaban @ Shahil.

Brian
sumber
Namun, kadang-kadang, Anda perlu melakukannya secara dinamis; yaitu, tanpa tindakan langsung dari pengguna. Saya percaya itulah yang diinginkan OP.
jpaugh
1
Ya, jelas OP sudah mengetahui fungsi anchor link.
isherwood
4

Ini bekerja:

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

  e.preventDefault();

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

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

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

  }, 2000);

});

https://jsfiddle.net/68pnkfgd/

Cukup tambahkan kelas 'gulir' ke tautan apa pun yang ingin Anda menghidupkan

Chuck Le Butt
sumber
Bagus, mudah digunakan solusi. Terima kasih!
Smitty-Werben-Jager-Manjenson
3

Ini adalah skrip yang berfungsi yang akan menggulir halaman ke jangkar. Untuk mensetup, beri tautan anchor id yang cocok dengan atribut nama anchor yang ingin Anda gulir.

<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>
Rudy Lister
sumber
2

Saya tahu ini adalah pertanyaan yang sudah sangat lama, tetapi saya menemukan solusi jQuery yang mudah dan sederhana di css-trik . Itu yang saya gunakan sekarang.

$(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;
      }
    }
  });
});
Horacio
sumber
1
Pemilih melemparkan pengecualian di jquery 2.2.0. 0x800a139e - Kesalahan runtime JavaScript: Kesalahan sintaksis, ekspresi yang tidak dikenal: a [href * = #]: not ([href = #])
Bill Shihara
2

jQuery("a[href^='#']").click(function(){
    jQuery('html, body').animate({
        scrollTop: jQuery( jQuery(this).attr('href') ).offset().top
    }, 1000);
    return false;
});

Adam Pery
sumber
2

solusi vue2 ... tambahkan properti data sederhana untuk hanya memaksa pembaruan

  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;
 }
Yordan Georgiev
sumber
0

cara termudah untuk membuat peramban menggulir laman ke jangkar yang diberikan adalah dengan mengetik style.css * {scroll-behaviour: smooth;} dan di navigasi html Anda gunakan #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>

eslam elameen
sumber