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>

Erik Fischer
sumber
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
1
ini akan membantu Anda :: stackoverflow.com/questions/3432656/…
Sudhir Bastakoti

Jawaban:

178

melakukan:

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

Diperbarui Jsfiddle

Sudhir Bastakoti
sumber
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);
}
nico
sumber
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);
}
Ned Rockson
sumber
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);
};
Marek Lisý
sumber
2

Anda dapat menggunakan css dasar untuk mendapatkan scroll yang mulus

html {
  scroll-behavior: smooth;
}
Sardorbek Khalimov
sumber
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);
}
Programmer Pasif
sumber