Apakah mungkin untuk menghidupkan scrollTop dengan jQuery?

226

Saya ingin menggulir ke bawah dengan lancar. Saya tidak ingin harus menulis fungsi untuk itu - terutama jika jQuery sudah memilikinya.

Bryan Field
sumber

Jawaban:

463

Anda hanya dapat menggunakan .animate()satu scrollTopproperti, seperti ini:

$("html, body").animate({ scrollTop: "300px" });
Nick Craver
sumber
Sangat bagus .. tidak perlu menggunakan plugin untuk ini.
Amol M Kulkarni
15
Mengapa Anda membutuhkan keduanya htmldan body? Ada beberapa wawasan di sini: stackoverflow.com/questions/2123690/… , tetapi itu bukan jawaban yang lengkap.
Haralan Dobrev
28
tubuh digunakan oleh webkit, html digunakan oleh firefox.
Jory
2
FYI: Jika <html>memiliki overflow-x:hidden;animasi ini tidak akan berfungsi. (Mungkin tidak bekerja untuk overflow-y:hidden, dan overflow:hidden, tapi saya belum diuji.
collinhaines
1
Saya pikir bodybekerja di Chrome pada awal tahun ini, tetapi sekarang harus html.
Nick Davies
73

Jawaban Nick sangat bagus. Hati-hati saat menentukan fungsi lengkap () di dalam panggilan animate () karena akan dieksekusi dua kali karena Anda memiliki dua pemilih yang dinyatakan (html dan badan).

$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            alert('this alert will popup twice');
        }
    }
);

Inilah cara Anda dapat menghindari panggilan balik ganda.

var completeCalled = false;
$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            if(!completeCalled){
                completeCalled = true;
                alert('this alert will popup once');
            }
        }
    }
);
Kita
sumber
1
Pertanyaannya adalah, mengapa Anda menghidupkan 'html, tubuh' dan bukan hanya 'tubuh'?
Lior
21
Karena tergantung pada peramban mana Anda berada, Anda dapat menganimasikan tubuh atau html. Dengan menghidupkan KEDUA, Anda menutupi lebih banyak browser.
Bene
Tetapi dalam kasus ini hanya akan muncul sekali, juga jika harus dipanggil berulang kali (klik acara pada tombol) atau apakah saya melewatkan sesuatu?
HoGo
Ya, dalam hal ini hanya akan muncul satu kali. Jika Anda perlu menghidupkan berulang kali, Anda akan membuat variabel completeCalled lokal ke fungsi panggilan balik yang mengeksekusi fungsi bernyawa. Dengan begitu ia akan tetap muncul hanya sekali ketika Anda mengklik, tetapi itu akan muncul lagi (hanya sekali) ketika Anda mengklik lagi.
Kita
Untuk mencegah pemunculan fungsi panggilan balik ganda, Anda dapat menggunakan die()fungsi sebelum live()panggilan fungsi. Ini menjamin, bahwa live()pawang Anda akan dipanggil hanya sekali.
Lord Nighton
27

Jawaban Nick berfungsi dengan baik dan pengaturan standarnya bagus, tetapi Anda dapat lebih mengontrol gulir dengan menyelesaikan semua pengaturan opsional.

di sini terlihat seperti apa di API:

.animate( properties [, duration] [, easing] [, complete] )

sehingga Anda dapat melakukan sesuatu seperti ini:

.animate( 
    {scrollTop:'300px'},
    300,
    swing,
    function(){ 
       alert(animation complete! - your custom code here!); 
       } 
    )

di sini adalah halaman api fungsi jQuery .animate: http://api.jquery.com/animate/

pramuka
sumber
15

Seperti Kita sebutkan ada masalah dengan beberapa panggilan balik yang diaktifkan ketika Anda menghidupkan baik 'html' dan 'tubuh'. Alih-alih menggerakkan keduanya dan memblokir panggilan balik berikutnya, saya lebih suka menggunakan beberapa deteksi fitur dasar dan hanya menggerakkan properti scrollTop dari satu objek.

Jawaban yang diterima di utas lain ini memberikan beberapa wawasan mengenai properti scrollTop objek mana yang harus kita coba untuk menghidupkan: pageYOffset Scrolling and Animation in IE8

// UPDATE: don't use this... see below
// only use 'body' for IE8 and below
var scrollTopElement = (window.pageYOffset != null) ? 'html' : 'body';

// only animate on one element so our callback only fires once!
$(scrollTopElement).animate({ 
        scrollTop: '400px' // vertical position on the page
    },
    500, // the duration of the animation 
    function() {       
        // callback goes here...
    })
});

PEMBARUAN - - -

Upaya deteksi fitur di atas gagal. Sepertinya tidak ada cara satu-line untuk melakukannya sebagai halaman web jenis peramban webKetika properti selalu kembali nol ketika ada DOCTYPE. Sebaliknya, saya menemukan cara untuk menggunakan janji untuk melakukan panggilan balik tunggal untuk setiap kali animasi dijalankan.

$('html, body')
    .animate({ scrollTop: 100 })
    .promise()
    .then(function(){
        // callback code here
    })
});
Stephen
sumber
1
Menggunakan janji () di sini jenius.
Allan Bazinet
Ini membutuhkan lebih banyak upvotes. Saya belum pernah melihat janji yang digunakan untuk ini sebelumnya, dan ini adalah sesuatu yang akhirnya saya cari setiap beberapa bulan. Seperti yang dikatakan Allan, jenius.
Tortilaman
14

Saya memiliki apa yang saya yakini sebagai solusi yang lebih baik daripada $('html, body')retas.

Ini bukan one-liner, tetapi masalah yang saya miliki $('html, body')adalah bahwa jika Anda login$(window).scrollTop() selama animasi, Anda akan melihat bahwa nilainya melonjak di semua tempat, kadang-kadang oleh ratusan piksel (meskipun saya tidak melihat hal seperti itu) terjadi secara visual). Saya membutuhkan nilainya agar dapat diprediksi, sehingga saya dapat membatalkan animasi jika pengguna meraih bilah gulir atau memutar roda mouse selama gulir otomatis.

Berikut adalah fungsi yang akan menghidupkan gulir dengan lancar:

function animateScrollTop(target, duration) {
    duration = duration || 16;
    var scrollTopProxy = { value: $(window).scrollTop() };
    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target }, 
            { duration: duration, step: function (stepValue) {
                var rounded = Math.round(stepValue);
                $(window).scrollTop(rounded);
            }
        });
    }
}

Di bawah ini adalah versi yang lebih kompleks yang akan membatalkan animasi pada interaksi pengguna, serta memperbarui hingga nilai target tercapai, yang berguna ketika mencoba untuk mengatur scrollTop secara instan (misalnya hanya memanggil $(window).scrollTop(1000)- dalam pengalaman saya, ini gagal untuk bekerja tentang 50% dari waktu.)

function animateScrollTop(target, duration) {
    duration = duration || 16;

    var $window = $(window);
    var scrollTopProxy = { value: $window.scrollTop() };
    var expectedScrollTop = scrollTopProxy.value;

    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target },
            {
                duration: duration,

                step: function (stepValue) {
                    var roundedValue = Math.round(stepValue);
                    if ($window.scrollTop() !== expectedScrollTop) {
                        // The user has tried to scroll the page
                        $(scrollTopProxy).stop();
                    }
                    $window.scrollTop(roundedValue);
                    expectedScrollTop = roundedValue;
                },

                complete: function () {
                    if ($window.scrollTop() != target) {
                        setTimeout(function () {
                            animateScrollTop(target);
                        }, 16);
                    }
                }
            }
        );
    }
}
John Starr Dewar
sumber
7

Saya mengalami masalah di mana animasi selalu dimulai dari bagian atas halaman setelah refresh halaman dalam contoh lain.

Saya memperbaikinya dengan tidak menghidupkan css secara langsung tetapi memanggil window.scrollTo();setiap langkah:

$({myScrollTop:window.pageYOffset}).animate({myScrollTop:300}, {
  duration: 600,
  easing: 'swing',
  step: function(val) {
    window.scrollTo(0, val);
  }
});

Ini juga mengatasi masalah htmlvs bodykarena menggunakan JavaScript lintas-browser.

Lihatlah http://james.padolsey.com/javascript/fun-with-jquerys-animate/ untuk informasi lebih lanjut tentang apa yang dapat Anda lakukan dengan fungsi bernyawa jQuery.

complistic
sumber
5

Anda dapat menggunakan animasi jQuery untuk halaman gulir dengan durasi tertentu:

$("html, body").animate({scrollTop: "1024px"}, 5000);

di mana 1024px adalah offset gulir dan 5000 adalah durasi animasi dalam milidetik.

Alessandro Pirovano
sumber
Jawaban bagus! Senang Anda memasukkan opsi durasi. Hanya ingin menambahkan itu $("html, body").animate({scrollTop: 1024}, 5000);juga berfungsi.
Ryan Taylor
4

Coba plugin scrollTo .

Tatu Ulmanen
sumber
Tampaknya scrollTo tidak lagi proyek di situs itu.
Jim
Kode untuk mencapai ini sangat sederhana. Mengapa Anda menambahkan plugin untuk melakukan sesuatu yang dapat Anda lakukan dengan satu baris kode?
Gavin
4
Empat tahun lalu itu tidak sesederhana itu .. :)
Tatu Ulmanen
4
$(".scroll-top").on("click", function(e){
   e.preventDefault();
   $("html, body").animate({scrollTop:"0"},600);
});
Rubel Hossain
sumber
1

Jika Anda ingin pindah ke bagian bawah halaman (sehingga Anda tidak perlu menggulir ke bawah), Anda dapat menggunakan:

$('body').animate({ scrollTop: $(document).height() });
Semut kecil
sumber
0

Tetapi jika Anda benar-benar ingin menambahkan beberapa animasi saat menggulir, Anda dapat mencoba plugin sederhana saya ( AnimateScroll ) yang saat ini mendukung lebih dari 30 gaya pelonggaran

Ram Patra
sumber
-3

kode lintas browser adalah:

$(window).scrollTop(300); 

itu tanpa animasi tetapi bekerja di mana-mana

pengguna2760861
sumber
6
Saya mencari cara "untuk menghidupkan scrollTop dengan jQuery?" Jawaban yang "tanpa animasi" bukanlah jawaban.
Lapangan Bryan