Gulir halus ke div tertentu saat diklik


94

Apa yang saya coba lakukan adalah membuatnya sehingga jika Anda mengklik sebuah tombol, tombol itu akan bergulir ke bawah (dengan lancar) ke div tertentu pada halaman.

Yang saya butuhkan adalah jika Anda mengklik tombolnya, itu akan menggulung halus ke div 'detik'.

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}
<div class="first"><button type="button">Click Me!</button></div>
<div class="second">Hi</div>


Anda dapat mencoba plugin ini Meskipun, yang ini jauh lebih ramah pengguna. Anda cukup banyak hanya perlu menautkan file JS di header, dan mengubah markup Anda dengan benar agar berfungsi.
joshrathke

Jawaban:


178

melakukan:

$("button").click(function() {
    $('html,body').animate({
        scrollTop: $(".second").offset().top},
        'slow');
});

Diperbarui Jsfiddle


Apakah Anda menggunakan javaScript di sini atau jQuery?

1
@FahadUdin jQuery nya.
Sudhir Bastakoti

@SudhirBastakoti: Mengapa JsFiddle tidak menyertakan pustaka jquery untuknya di halaman itu?

@Sudhir Bastakoti tetapi banyak pengguna mengeluh karena penggulirannya tidak lancar.
Maulik

40

Ada banyak contoh pengguliran halus menggunakan pustaka JS seperti jQuery, Mootools, Prototype, dll.

Contoh berikut adalah pada JavaScript murni. Jika Anda tidak memiliki jQuery / Mootools / Prototype di halaman atau Anda tidak ingin membebani halaman dengan library JS yang berat, contohnya akan membantu.

http://jsfiddle.net/rjSfP/

Bagian HTML:

<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div>
<div class="second" id="second">Hi</div>

Bagian CSS:

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}

Bagian JS:

window.smoothScroll = function(target) {
    var scrollContainer = target;
    do { //find scroll container
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do { //find the top of target relatively to the container
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    scroll = function(c, a, b, i) {
        i++; if (i > 30) return;
        c.scrollTop = a + (b - a) / 30 * i;
        setTimeout(function(){ scroll(c, a, b, i); }, 20);
    }
    // start scrolling
    scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}

Saya menggunakan ini dan itu bekerja dengan baik. Bagaimana cara membuat scroll lebih lambat?
jamescampbell

Ada ide bagaimana menambahkan offset untuk navbar tetap dalam kode ini? Berikut adalah contoh yang saya buat biola
Plavookac

3
Masih membantu setelah 5 tahun
Owaiz Yusufi

9

Saya bermain-main dengan jawaban nico sedikit dan rasanya gelisah. Melakukan sedikit penyelidikan dan menemukan window.requestAnimationFramefungsi yang dipanggil pada setiap siklus pengecatan ulang. Ini memungkinkan animasi yang tampak lebih bersih. Masih mencoba untuk mengasah nilai default yang baik untuk ukuran langkah tetapi untuk contoh saya hal-hal terlihat cukup bagus menggunakan implementasi ini.

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var stepFunc = function() {
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}

1
@Alonso Lihat di atas. Ini hanyalah versi kode nico yang dioptimalkan dalam jawaban sebelumnya.
Ned Rockson

@NedRockson Tidak bekerja untuk saya memberikan pesan konsol "Tidak Tertangkap TypeError: Tidak dapat membaca properti 'parentNode' dari null" tetapi kode nico berfungsi, Apa yang harus saya lakukan agar dapat menerapkan animasi bersih?
Kartik Watwani

@KartikWatwani Itu berarti bahwa pada pembacaan baris scrollContainer = scrollContainer.parentNode, scrollContainer adalah null. Ini kemungkinan berarti Anda tidak memberikan jawaban yang benar elementIdsaat memanggil fungsi ini. Mungkin juga Anda menjalankan skrip ini pada halaman di mana elementId itu tidak ada.
Ned Rockson

@NedRockson Jika elementIdakan salah saya akan menerima kesalahan yang sama dalam kasus contoh @nico tetapi dalam kasus ini pengguliran berfungsi tetapi tidak lancar.
Kartik Watwani

Menggunakan requestAnimationFramealih-alih setTimeoutadalah cara yang harus dilakukan. setTimeouttidak boleh digunakan untuk animasi.
tsnkff


2

Saya mengambil versi Ned Rockson dan menyesuaikannya untuk memungkinkan gulungan ke atas juga.

var smoothScroll = function(elementId) {
  var MIN_PIXELS_PER_STEP = 16;
  var MAX_SCROLL_STEPS = 30;
  var target = document.getElementById(elementId);
  var scrollContainer = target;
  do {
    scrollContainer = scrollContainer.parentNode;
    if (!scrollContainer) return;
    scrollContainer.scrollTop += 1;
  } while (scrollContainer.scrollTop === 0);

  var targetY = 0;
  do {
    if (target === scrollContainer) break;
    targetY += target.offsetTop;
  } while (target = target.offsetParent);

  var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
    Math.abs(targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

  var isUp = targetY < scrollContainer.scrollTop;

  var stepFunc = function() {
    if (isUp) {
      scrollContainer.scrollTop = Math.max(targetY, scrollContainer.scrollTop - pixelsPerStep);
      if (scrollContainer.scrollTop <= targetY) {
        return;
      }
    } else {
        scrollContainer.scrollTop = Math.min(targetY, scrollContainer.scrollTop + pixelsPerStep);

      if (scrollContainer.scrollTop >= targetY) {
        return;
      }
    }

    window.requestAnimationFrame(stepFunc);
  };

  window.requestAnimationFrame(stepFunc);
};

2

Anda dapat menggunakan css dasar untuk mendapatkan scroll yang mulus

html {
  scroll-behavior: smooth;
}

0

Ned Rockson pada dasarnya menjawab pertanyaan ini. Namun ada kesalahan fatal dalam solusinya. Saat elemen yang ditargetkan lebih dekat ke bagian bawah halaman daripada tinggi viewport, fungsi tersebut tidak mencapai pernyataan keluarnya dan menjebak pengguna di bagian bawah halaman. Ini hanya diselesaikan dengan membatasi jumlah iterasi.

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var iterations = 0;
    var stepFunc = function() {
        if(iterations > MAX_SCROLL_STEPS){
            return;
        }
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.