jQueryでscrollTopをアニメーション化することは可能ですか?


回答:


463

次のように.animate()scrollTopプロパティを使用できます。

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

とてもいいです。このためにプラグインを使う必要はありません。
Amol M Kulkarni 2013

15
htmlとの両方が必要なのはなぜbodyですか?ここにいくつかの洞察があります:stackoverflow.com/questions/2123690/…、しかしそれは完全な答えではありません。
Haralan Dobrev

28
bodyはwebkitで使用され、htmlはfirefoxで使用されます。
ジョリー2014

2
FYI:もしが<html>ありoverflow-x:hidden;、このアニメーションが動作しません。(overflow-y:hiddenoverflow:hidden
、、、

1
body今年の初めの時点ではChromeで働いていたと思いますが、今はそうでなければなりませんhtml
ニックデイビス

73

ニックの答えはうまくいきます。2つのセレクター(htmlとbody)が宣言されているため、animate()呼び出し内でcomplete()関数を指定するときは、2回実行されるので注意してください。

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

これが二重のコールバックを回避する方法です。

var completeCalled = false;
$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            if(!completeCalled){
                completeCalled = true;
                alert('this alert will popup once');
            }
        }
    }
);

1
問題は、「ボディ」だけでなく、「HTML、ボディ」をアニメーション化する理由は何ですか?
Lior

21
使用しているブラウザに応じて、本文またはHTMLをアニメーション化できるからです。両方をアニメーション化することで、より多くのブラウザーをカバーできます。
2013年

しかし、この場合、繰り返し呼び出される必要がある場合(ボタンのイベントをクリック)、または何かを逃した場合でも、ポップアップは本当に1回だけ表示されますか?
HoGo

はい、この場合、ポップアップするのは1回だけです。繰り返しアニメーション化する必要がある場合は、completeCalled変数を、アニメーション化関数を実行するコールバック関数に対してローカルにします。このように、クリックすると1回だけポップアップしますが、もう一度クリックすると再び(1回だけ)ポップアップします。

二重のコールバック関数の発火を防ぐdie()には、live()関数を呼び出す前にfunctionを使用できます。これにより、live()ハンドラーが1回だけ呼び出されることが保証されます。
Lord Nighton、2015年

27

ニックの答えはうまく機能し、デフォルト設定は適切ですが、すべてのオプション設定を完了することで、スクロールをより完全に制御できます。

APIでの表示は次のとおりです。

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

だからあなたはこのようなことをすることができます:

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

ここにjQueryの.animate関数のapiページがあります:http ://api.jquery.com/animate/


15

Kitaが述べたように、「html」と「body」の両方でアニメートすると、複数のコールバックが起動するという問題があります。両方をアニメーション化して後続のコールバックをブロックする代わりに、いくつかの基本的な機能検出を使用して、単一のオブジェクトのscrollTopプロパティのみをアニメーション化することを好みます。

この他のスレッドで受け入れられた回答は、アニメーション化する必要があるオブジェクトのscrollTopプロパティについての洞察を提供します:IE8でのpageYOffsetスクロールとアニメーション

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

更新---

上記の機能検出の試みは失敗します。doctypeがある場合、webkitタイプのブラウザーのpageYOffsetプロパティは常にゼロを返すため、これを行う1行の方法はないようです。代わりに、アニメーションを実行するたびに単一のコールバックを行うというpromiseを使用する方法を見つけました。

$('html, body')
    .animate({ scrollTop: 100 })
    .promise()
    .then(function(){
        // callback code here
    })
});

1
ここでpromise()を使用するのは天才です。
Allan Bazinet 2016年

これにはもっと賛成票が必要です。私はこれまでこれに使用される約束を見たことがありません、そしてこれは私が数ヶ月ごとに検索することになるものです。アランが言ったように、天才。
トルティラマン2018

14

私はより良い解決策であると私が信じているものを持っています $('html, body')ハックます。

ワンライナーではありませんが、私が抱えていた問題$('html, body')は、$(window).scrollTop()、アニメーション中にと、値が場所を飛び越えて、場合によっては数百ピクセルもジャンプすることがわかります(私はそのようなものは何も表示しませんが)視覚的に起こります)。自動スクロール中にユーザーがスクロールバーをつかんだり、マウスホイールを回したりした場合にアニメーションをキャンセルできるように、値を予測可能にする必要がありました。

以下は、スクロールをスムーズにアニメーション化する関数です。

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

以下はより複雑なバージョンで、ユーザーインタラクションでアニメーションをキャンセルするだけでなく、ターゲット値に到達するまで再起動します。これは、scrollTopを瞬時に設定しようとする場合に便利です(たとえば、単に呼び出します$(window).scrollTop(1000)—私の経験では、これは機能しません。時間の50%)

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

7

他の例でページを更新した後、アニメーションが常にページの先頭から開始されるという問題がありました。

私はCSSを直接​​アニメーション化せずにwindow.scrollTo();、各ステップを呼び出すことでこれを修正しました:

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

これは、クロスブラウザーJavaScriptを使用しているため、htmlvs body問題も回避します。

jQueryのanimate関数で実行できることの詳細については、http://james.padolsey.com/javascript/fun-with-jquerys-animate/を参照してください。


5

特定の期間のスクロールページにjQueryアニメーションを使用できます。

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

ここで、1024pxはスクロールオフセット、5000はアニメーションの継続時間(ミリ秒)です。


正解です。期間オプションを含めてよかったです。追加したかっただけ$("html, body").animate({scrollTop: 1024}, 5000);でも動作します。
ライアンテイラー

4

scrollTo プラグインを試してください 。


scrollToはそのサイトのプロジェクトではなくなったようです。
ジム、

これを達成するためのコードはとても単純です。なぜ1行のコードでできることをするためにプラグインを追加するのですか?
Gavin、

4
4年前はそれほど単純ではなかった.. :)
Tatu Ulmanen 14年


1

ページの最後に下に移動したい場合(下にスクロールする必要がない場合)は、以下を使用できます。

$('body').animate({ scrollTop: $(document).height() });

0

しかし、スクロール中にアニメーションを追加したい場合は、現在30以上のイージングスタイルをサポートしている単純なプラグイン(AnimateScroll)を試すことができます。


-3

クロスブラウザコードは次のとおりです。

$(window).scrollTop(300); 

アニメーションはありませんが、どこでも機能します


6
「jQueryでscrollTopをアニメーション化する方法」を探していました。「アニメーションなし」の答えは答えではありません。
ブライアンフィールド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.