国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目次
畫面の後ろにすばやく理解してください
もちろん、登録されているイベントリスナー(OnClick)では、受信クリックイベントオブジェクトのターゲットをチェックして、ページのリンク要素に関連しているかどうかを確認する必要があります。これはさまざまな方法で行うことができるため、ヘルパー関數isinpagelink()として抽象化します。この機能のメカニズムを後で見ていきます。
コールバックで実行され、ジャンプ機能に渡し、スクロールしたい要素のハッシュを過去に渡します:
。
私たちが書いたコードで(CSSサポートが利用できない場合、それをフォールバックスキームと考えることができます)、ブラウザの履歴に対するスクリプトの動作を考慮しませんでした。コンテキストとユースケースに応じて、これは興味深いものである場合とそうでない場合がありますが、スクリプトがデフォルトのスクロールエクスペリエンスを強化する必要があると考える場合、CSSのように一貫した動作を期待する必要があります。
FAQ(FAQ)
ライブラリを使用せずにネイティブJavaScriptを使用してスムーズなスクロールを実現するにはどうすればよいですか?
特定の要素にスムーズにスクロールするには、
を使用して、速度を含むスクロールアニメーションをより適切に制御するために、カスタムスムーズなスクロール機能を作成できます。
および
を使用してアニメーションフレームをキャンセルしてアニメーションを停止できます。
キーボードナビゲーションを使用してスムーズなスクロールを実現する方法は?
ホームページ ウェブフロントエンド jsチュートリアル バニラJavaScriptにスムーズなスクロールを実裝する方法

バニラJavaScriptにスムーズなスクロールを実裝する方法

Feb 18, 2025 am 10:49 AM

How to Implement Smooth Scrolling in Vanilla JavaScript

コアポイント

  • Jump.jsライブラリを使用して、ネイティブJavaScriptのスムーズなスクロールを実裝し、外部依存関係なしにスクロールアニメーションを簡素化します。
  • Jump.jsの元のコードを変更してES6からES5に変換して、さまざまなブラウザーとのより広い互換性を確保します。
  • requestAnimationFrameメソッドを使用して、スムーズなアニメーションの更新を実行し、パフォーマンスを最適化し、スムーズなユーザーエクスペリエンスを提供します。
  • カスタムJavaScriptを実裝して、デフォルトのページ內リンク動作をインターセプトし、突然のジャンプをスムーズなスクロールアニメーションに置き換えます。
  • この機能を認識するブラウザでのネイティブスムーススクロールをサポートするための統(tǒng)合されたCSS
  • プロパティと、ブラウザがサポートしていない場合はJavaScriptフォールバックメカニズムが提供されます。 scroll-behavior スクロール後にターゲット要素にフォーカスを設定し、キーボードナビゲーションの潛在的な問題に対処し、すべてのユーザーのユーザビリティを向上させることにより、アクセシビリティを確保します。
この記事は、エイドリアン?サンドゥ、クリス?ペリー、ジェレミー?ヘレイン、マロリー?ヴァン?アチェルバーグによって査読されました。 SitePointで最高のコンテンツを取得するためにSetePointのすべてのピアレビューアに感謝します!

Smooth Scrollingは、デフォルトの內部ナビゲーションエクスペリエンスを徐々に強化するユーザーインターフェイスモードであり、アクティベーションリンクの位置からリンクURLまで、スクロールボックス內の位置(ビューポートまたはスクロール可能な要素)をアニメーション化します。クリップに示されています。 これは新しいものではなく、長年にわたって既知のパターンでした。たとえば、2003年に遡るこのSitePointの記事をご覧ください!ちなみに、この投稿は、クライアント側のJavaScriptプログラミング、特にDOMが長年にわたってどのように変化および進化し、より簡単なネイティブJavaScriptソリューションの開発を可能にしているため、歴史的に価値があります。

jQueryエコシステムでは、このパターンには多くの実裝があり、jqueryまたはプラグインで直接実裝できますが、この記事では、純粋なJavaScriptソリューションに興味があります。具體的には、jump.jsライブラリを探索して利用します。

ライブラリとその機能と機能の概要を紹介した後、ニーズに合わせて元のコードにいくつかの変更を加えます。その過程で、関數や閉鎖などのコアJavaScript言語スキルをレビューします。次に、HTMLページを作成して、スムーズなスクロール動作をテストし、カスタムスクリプトとして実裝します。その後、CSSでのネイティブスムーススクロールのサポートが追加され(利用可能な場合)、最終的にブラウザナビゲーション履歴についていくつかの観察を行います。

これは、作成する最終的なデモです:

CodepenでSitePoint(@SitePoint)用の滑らかなスクロールペンを表示します。

完全なソースコードはGitHubで見つけることができます。

Jump.js

Jump.jsはネイティブES6 JavaScriptで記述されており、外部依存関係はありません。これはわずか42スロックしかない小規(guī)模ですが、提供される最小化パッケージのサイズは約2.67 kbで、翻訳する必要があります。 GitHubプロジェクトページにデモが提供されています。

名前が示すように、それはジャンプのみを提供します:スクロールバーの位置のアニメーションの変更は、現在の値からターゲット位置への変更、DOM要素、CSSセレクター、または正またはネガティブの形の距離を提供することによって指定されます數値。これは、スムーズなスクロールモードの実裝では、自分自身をハイジャックするリンクを実行する必要があることを意味します。詳細については、以下のセクションを參照してください。

現在、ビューポートの垂直スクロールのみがサポートされていることに注意してください。

期間(このパラメーターが必要)、アニメーションの最後にトリガーされるコールバックなど、いくつかのオプションを使用してジャンプを構成できます。デモの後半で彼らの実際のアプリケーションを見ることができます。詳細については、ドキュメントを參照してください。

Jump.jsは、Internet Explorerバージョン10以降など、問題なく「モダンな」ブラウザで実行されます。繰り返しますが、サポートされているブラウザの完全なリストについては、ドキュメントを參照してください。適切なRequestAnimationFrame PolyFillを使用すると、古いブラウザーで実行することもできます。

畫面の後ろにすばやく理解してください

內部的には、Jump.jsソースコードは、ウィンドウオブジェクトのRequestAnimationFrameメソッドを使用して、スクロールアニメーションの各フレームで更新されたViewPortの垂直位置の位置をアレンジします。この更新は、easing inasing関數をWindow.scrolltoメソッドに使用して計算された次の位置値を渡すことによって達成されます。詳細については、ソースコードを參照してください。

いくつかのカスタマイズ

デモを掘り下げる前に、元のコードにいくつかの小さな変更を加えて、Jump.jsの使用方法を示しますが、それが內部での動作方法を変更しません。

ソースコードはES6で記述されており、モジュールを翻訳およびバンドルするためのJavaScriptビルドツールで使用する必要があります。これは一部のプロジェクトでは少し多すぎるかもしれないので、リファクタリングを適用して、どこでも使用するためにコードをES5に変換します。

最初に、ES6の構文と機能を削除しましょう。スクリプトは、ES6クラスを定義します:

<code>import easeInOutQuad from './easing'

export default class Jump {
  jump(target, options = {}) {
    this.start = window.pageYOffset

    this.options = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    }

    this.distance = typeof target === 'string'
      ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
      : target

    this.duration = typeof this.options.duration === 'function'
      ? this.options.duration(this.distance)
      : this.options.duration

    requestAnimationFrame(time => this._loop(time))
  }

  _loop(time) {
    if(!this.timeStart) {
      this.timeStart = time
    }

    this.timeElapsed = time - this.timeStart
    this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

    window.scrollTo(0, this.next)

    this.timeElapsed       ? requestAnimationFrame(time => this._loop(time))
      : this._end()
  }

  _end() {
    window.scrollTo(0, this.start + this.distance)

    typeof this.options.callback === 'function' && this.options.callback()
    this.timeStart = false
  }
}
</code>
コンストラクターと多數のプロトタイプメソッドを使用してES5「クラス」に変換できますが、このクラスの複數のインスタンスは決して必要ないので、通常のオブジェクトで実裝されたシングルトンは問題ありません。

クラスを削除することに加えて、他の変更を加える必要があります。
<code>var jump = (function() {

    var o = {

        jump: function(target, options) {
            this.start = window.pageYOffset

            this.options = {
              duration: options.duration,
              offset: options.offset || 0,
              callback: options.callback,
              easing: options.easing || easeInOutQuad
            }

            this.distance = typeof target === 'string'
              ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
              : target

            this.duration = typeof this.options.duration === 'function'
              ? this.options.duration(this.distance)
              : this.options.duration

            requestAnimationFrame(_loop)
        },

        _loop: function(time) {
            if(!this.timeStart) {
              this.timeStart = time
            }

            this.timeElapsed = time - this.timeStart
            this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

            window.scrollTo(0, this.next)

            this.timeElapsed               ? requestAnimationFrame(_loop)
              : this._end()
        },

        _end: function() {
            window.scrollTo(0, this.start + this.distance)

            typeof this.options.callback === 'function' && this.options.callback()
            this.timeStart = false
        }

    };

    var _loop = o._loop.bind(o);

    // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
    function easeInOutQuad(t, b, c, d)  {
        t /= d / 2
        if(t         t--
        return -c / 2 * (t * (t - 2) - 1) + b
    }

    return o;

})();
</code>
のコールバックは、各フレームのスクロールバーの位置を更新するために使用され、元のコードでは、ES6矢印関數を介して呼び出され、初期化時にジャンプシングルトンにプリバウンドします。次に、同じソースファイルにデフォルトの緩和関數をバンドルします。最後に、名前空間汚染を避けるために、Iife(すぐに関數式を呼び出す)を使用してコードをラップします。

requestAnimationFrame別の再構成ステップを適用できます。ネストされた機能と閉鎖の助けを借りて、オブジェクトの代わりに関數を使用できることに注意してください。

シングルトンは、アニメーションスクロール、ループ、エンドのコールバックがネストされた関數になるように呼び出されるジャンプ関數であり、オブジェクトのプロパティがローカル変數(クロージャー)になります。すべてのコードが機能に安全にラップされているため、Iifeはもう必要ありません。

最終的なリファクタリングステップとして、ループコールバックが呼び出されるたびに繰り返しのタイムスタートリセットチェックを回避するために、最初の時間requestAnimationFrame()が呼び出されます。匿名関數を渡します。ループ関數リセットTimerStART変數:

<code>import easeInOutQuad from './easing'

export default class Jump {
  jump(target, options = {}) {
    this.start = window.pageYOffset

    this.options = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    }

    this.distance = typeof target === 'string'
      ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
      : target

    this.duration = typeof this.options.duration === 'function'
      ? this.options.duration(this.distance)
      : this.options.duration

    requestAnimationFrame(time => this._loop(time))
  }

  _loop(time) {
    if(!this.timeStart) {
      this.timeStart = time
    }

    this.timeElapsed = time - this.timeStart
    this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

    window.scrollTo(0, this.next)

    this.timeElapsed       ? requestAnimationFrame(time => this._loop(time))
      : this._end()
  }

  _end() {
    window.scrollTo(0, this.start + this.distance)

    typeof this.options.callback === 'function' && this.options.callback()
    this.timeStart = false
  }
}
</code>
再構成プロセス中に、コアスクロールアニメーションコードが変更されていないことに再度注意してください。

テストページ

ニーズに合わせてスクリプトをカスタマイズしたので、テストデモを組み立てる準備ができました。このセクションでは、次のセクションで説明したスクリプトを使用してスムーズなスクロールを強化するページを書きます。

このページには、ドキュメントの以降のセクションのページ內のリンクを指し、TOCへの他のリンクを指す目次(TOC)が含まれています。また、いくつかの外部リンクを他のページに組み合わせます。これは、このページの基本構造です:

<code>var jump = (function() {

    var o = {

        jump: function(target, options) {
            this.start = window.pageYOffset

            this.options = {
              duration: options.duration,
              offset: options.offset || 0,
              callback: options.callback,
              easing: options.easing || easeInOutQuad
            }

            this.distance = typeof target === 'string'
              ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
              : target

            this.duration = typeof this.options.duration === 'function'
              ? this.options.duration(this.distance)
              : this.options.duration

            requestAnimationFrame(_loop)
        },

        _loop: function(time) {
            if(!this.timeStart) {
              this.timeStart = time
            }

            this.timeElapsed = time - this.timeStart
            this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

            window.scrollTo(0, this.next)

            this.timeElapsed               ? requestAnimationFrame(_loop)
              : this._end()
        },

        _end: function() {
            window.scrollTo(0, this.start + this.distance)

            typeof this.options.callback === 'function' && this.options.callback()
            this.timeStart = false
        }

    };

    var _loop = o._loop.bind(o);

    // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
    function easeInOutQuad(t, b, c, d)  {
        t /= d / 2
        if(t         t--
        return -c / 2 * (t * (t - 2) - 1) + b
    }

    return o;

})();
</code>
頭には、基本的な最も単純なレイアウトを設定するためのいくつかのCSSルールを含め、ボディタグの最後に2つのJavaScriptファイルを含めます。それは私たちが今議論するスクリプトですか?

メインスクリプト

これは、jump.jsライブラリのカスタマイズされたバージョンからのアニメーションジャンプを使用して、テストページスクロールエクスペリエンスを強化するスクリプトです。もちろん、このコードはES5 JavaScriptにも記述されます。

すべきことの簡単な概要を見てみましょう:ページ內のリンクのクリックをハイジャックする必要があります。リンク、そしてJump()関數への呼び出しに置き換えます。

したがって、まず、ページのリンクのクリックを監(jiān)視する必要があります。これを2つの方法で行うことができます。イベントデリゲートを使用するか、関連する各リンクにハンドラーを添付します。 イベント委員會

最初の方法では、クリックリスナーを要素document.bodyに追加します。このようにして、ページ上の任意の要素のクリックイベントごとに、祖先の枝に沿ってドキュメントに到達するまでdomツリーに泡立ちます。

著信クリックがページ內リンクにある場合、イベントバブルを停止し、関連するデフォルトアクションをブロックします。最後に、ジャンプ関數を呼び出して、ターゲット要素のハッシュセレクターと、必要なアニメーションを構成するパラメーターを提供します。

<code>function jump(target, options) {
    var start = window.pageYOffset;

    var opt = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    };

    var distance = typeof target === 'string' ? 
        opt.offset + document.querySelector(target).getBoundingClientRect().top : 
        target
    ;

    var duration = typeof opt.duration === 'function'
          ? opt.duration(distance)
          : opt.duration
    ;

    var 
        timeStart = null,
        timeElapsed
    ;

    requestAnimationFrame(loop);

    function loop(time) {
        if (timeStart === null)
            timeStart = time;

        timeElapsed = time - timeStart;

        window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration));

        if (timeElapsed         requestAnimationFrame(loop)
        else
            end();
    }

    function end() {
        window.scrollTo(0, start + distance);

        typeof opt.callback === 'function' && opt.callback();
        timeStart = null;
    }

    // ...

}
</code>
これはイベントハンドラーです:

シングルハンドラー

2番目のメソッドを使用してリンククリックを監(jiān)視し、上記のイベントハンドラーのわずかに変更されたバージョンを各ページ內のリンク要素に添付するため、イベントバブルはありません:

<code>import easeInOutQuad from './easing'

export default class Jump {
  jump(target, options = {}) {
    this.start = window.pageYOffset

    this.options = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    }

    this.distance = typeof target === 'string'
      ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
      : target

    this.duration = typeof this.options.duration === 'function'
      ? this.options.duration(this.distance)
      : this.options.duration

    requestAnimationFrame(time => this._loop(time))
  }

  _loop(time) {
    if(!this.timeStart) {
      this.timeStart = time
    }

    this.timeElapsed = time - this.timeStart
    this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

    window.scrollTo(0, this.next)

    this.timeElapsed       ? requestAnimationFrame(time => this._loop(time))
      : this._end()
  }

  _end() {
    window.scrollTo(0, this.start + this.distance)

    typeof this.options.callback === 'function' && this.options.callback()
    this.timeStart = false
  }
}
</code>

すべての要素をクエリし、.slice()Trickを使用して、返されたDOMノデリストをJavaScriptアレイに変換します(ターゲットブラウザがES6 Array.from()を使用する場合、より良い代替手段方法)。次に、配列メソッドを使用してページ內のリンクをフィルタリングし、上記の同じヘルパー関數を再利用し、最後にリスナーを殘りのリンク要素に接続できます。 []

イベントハンドラーは以前とほぼ同じですが、もちろんクリックターゲットを確認する必要はありません。

どのメソッドが使用のコンテキストに依存するのが最適です。たとえば、最初のページの読み込み後に新しいリンク要素を動的に追加できる場合、イベントデリゲートを使用する必要があります。
<code>var jump = (function() {

    var o = {

        jump: function(target, options) {
            this.start = window.pageYOffset

            this.options = {
              duration: options.duration,
              offset: options.offset || 0,
              callback: options.callback,
              easing: options.easing || easeInOutQuad
            }

            this.distance = typeof target === 'string'
              ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
              : target

            this.duration = typeof this.options.duration === 'function'
              ? this.options.duration(this.distance)
              : this.options.duration

            requestAnimationFrame(_loop)
        },

        _loop: function(time) {
            if(!this.timeStart) {
              this.timeStart = time
            }

            this.timeElapsed = time - this.timeStart
            this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

            window.scrollTo(0, this.next)

            this.timeElapsed               ? requestAnimationFrame(_loop)
              : this._end()
        },

        _end: function() {
            window.scrollTo(0, this.start + this.distance)

            typeof this.options.callback === 'function' && this.options.callback()
            this.timeStart = false
        }

    };

    var _loop = o._loop.bind(o);

    // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
    function easeInOutQuad(t, b, c, d)  {
        t /= d / 2
        if(t         t--
        return -c / 2 * (t * (t - 2) - 1) + b
    }

    return o;

})();
</code>

ここで、Isinpagelink()の実裝に目を向けます。これは、以前のイベントハンドラーでこのヘルパー機能を使用して、ページのリンクのテストを抽象化しました。ご覧のとおり、この関數はDOMノードをパラメーターとして取得し、ブール値を返して、ノードがページのリンク要素を表すかどうかを示します。リンクが別のページを指している可能性があるため、通過したノードがAタグであり、ハッシュフラグメントが設定されていることを確認するだけでは十分ではありません。その場合、デフォルトのブラウザアクションを無効にする必要はありません。したがって、プロパティHREFに保存されている値「マイナス」ハッシュフラグメントがページURLに等しいかどうかを確認します。

StripHash()は別のヘルパー関數であり、スクリプトが初期化されたときに変數pageURLの値を設定するためにも使用します。

<code>function jump(target, options) {
    var start = window.pageYOffset;

    var opt = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    };

    var distance = typeof target === 'string' ? 
        opt.offset + document.querySelector(target).getBoundingClientRect().top : 
        target
    ;

    var duration = typeof opt.duration === 'function'
          ? opt.duration(distance)
          : opt.duration
    ;

    var 
        timeStart = null,
        timeElapsed
    ;

    requestAnimationFrame(loop);

    function loop(time) {
        if (timeStart === null)
            timeStart = time;

        timeElapsed = time - timeStart;

        window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration));

        if (timeElapsed         requestAnimationFrame(loop)
        else
            end();
    }

    function end() {
        window.scrollTo(0, start + distance);

        typeof opt.callback === 'function' && opt.callback();
        timeStart = null;
    }

    // ...

}
</code>
この文字列ベースのソリューションとハッシュフラグメントの剪定は、ハッシュパーツがURLの一般的な構造にあるため、クエリ文字列を備えたURLでも正常に機能します。

前に言ったように、これはこのテストを実裝する1つの可能な方法にすぎません。たとえば、このチュートリアルの冒頭で引用された記事では、異なるソリューションを使用して、リンクHREFのコンポーネントレベルの比較をロケーションオブジェクトと実行します。

<code>requestAnimationFrame(function(time) { timeStart = time; loop(time); });

function loop(time) {
    timeElapsed = time - timeStart;

    window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration));

    if (timeElapsed         requestAnimationFrame(loop)
    else
        end();
}
</code>
この関數は両方のイベントサブスクリプションメソッドで使用していることに注意してくださいが、2番目の方法では、既に知っている要素のフィルターとして使用していることに注意してください。冗長。これは、演習として読者に任されています。

アクセシビリティの考慮事項

今のところ、私たちのコードは、キーボードユーザーに影響を與える既知のエラー(実際には、Blink/webkit/khtmlに影響する無関係なエラーとIEに影響するエラーのペア)の影響を受けやすいです。 TOCリンクをタブキーを介して閲覧すると、リンクをアクティブにすると、選択したセクションまでスムーズにスクロールしますが、リンクには焦點が殘ります。これは、次のタブキーが押されると、ユーザーが選択したセクションの最初のリンクの代わりにTOCに送り返されることを意味します。 この問題を解決するために、メインスクリプトに別の関數を追加します:

コールバックで実行され、ジャンプ機能に渡し、スクロールしたい要素のハッシュを過去に渡します:

<code>import easeInOutQuad from './easing'

export default class Jump {
  jump(target, options = {}) {
    this.start = window.pageYOffset

    this.options = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    }

    this.distance = typeof target === 'string'
      ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
      : target

    this.duration = typeof this.options.duration === 'function'
      ? this.options.duration(this.distance)
      : this.options.duration

    requestAnimationFrame(time => this._loop(time))
  }

  _loop(time) {
    if(!this.timeStart) {
      this.timeStart = time
    }

    this.timeElapsed = time - this.timeStart
    this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

    window.scrollTo(0, this.next)

    this.timeElapsed       ? requestAnimationFrame(time => this._loop(time))
      : this._end()
  }

  _end() {
    window.scrollTo(0, this.start + this.distance)

    typeof this.options.callback === 'function' && this.options.callback()
    this.timeStart = false
  }
}
</code>

この関數の関數は、ハッシュ値に対応するDOM要素を取得し、既にフォーカスを受信できる要素(アンカーやボタン要素など)であるかどうかをテストすることです。要素がデフォルトでフォーカス(コンテナなど)でフォーカスを受信できない場合、Tabindexプロパティを-1に設定します(プログラムでフォーカスを受信できますが、キーボードを介してではなく)。その後、焦點はその要素に設定されます。つまり、ユーザーの次のタブキーは、フォーカスを次の利用可能なリンクに移動します。 ここでは、メインスクリプトの完全なソースコードを表示できます。すべての変更について前述しました。

CSSを使用したネイティブの滑らかなスクロールをサポートします

CSSオブジェクトモデルビューモジュール仕様は、スムーズなスクロールをネイティブに実裝するための新しいプロパティを導入します:

2つの値を取ることができ、scroll-behaviorはデフォルトの瞬時スクロールを表し、

はアニメーションスクロールを表します。この仕様では、その持続時間や時間関數(緩和)などのスクロールアニメーションを構成する方法は提供されません。

autoCSS-Scroll-Behaviorを使用できますか? Caniuse.comからのデータは、主要なブラウザによるCSSスクロール行動機能のサポートを示しています。 smooth

殘念ながら、執(zhí)筆時點では、サポートは非??常に限られています。 Chromeでは、この機能は開発中であり、Chrome:// Flags畫面で有効にすることで部分的に実裝できます。 CSSプロパティはまだ実裝されていないため、リンククリックのスムーズなスクロールは機能しません。

とにかく、メインスクリプトに小さな変更を加えることで、この機能がユーザーエージェントで利用可能であるかどうかを検出し、殘りのコードの実行を避けることができます。ビューポートで滑らかなスクロールを使用するために、css屬性をルート要素htmlに適用します(ただし、テストページでは、ボディ要素にも適用できます):

次に、スクリプトの先頭に単純な機能検出テストを追加します:

<code>var jump = (function() {

    var o = {

        jump: function(target, options) {
            this.start = window.pageYOffset

            this.options = {
              duration: options.duration,
              offset: options.offset || 0,
              callback: options.callback,
              easing: options.easing || easeInOutQuad
            }

            this.distance = typeof target === 'string'
              ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
              : target

            this.duration = typeof this.options.duration === 'function'
              ? this.options.duration(this.distance)
              : this.options.duration

            requestAnimationFrame(_loop)
        },

        _loop: function(time) {
            if(!this.timeStart) {
              this.timeStart = time
            }

            this.timeElapsed = time - this.timeStart
            this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

            window.scrollTo(0, this.next)

            this.timeElapsed               ? requestAnimationFrame(_loop)
              : this._end()
        },

        _end: function() {
            window.scrollTo(0, this.start + this.distance)

            typeof this.options.callback === 'function' && this.options.callback()
            this.timeStart = false
        }

    };

    var _loop = o._loop.bind(o);

    // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
    function easeInOutQuad(t, b, c, d)  {
        t /= d / 2
        if(t         t--
        return -c / 2 * (t * (t - 2) - 1) + b
    }

    return o;

})();
</code>
したがって、ブラウザがネイティブのスクロールをサポートしている場合、スクリプトは何もしず、終了します。そうしないと、以前と同じように実行され続け、ブラウザはサポートされていないCSSプロパティを無視します。

結論
<code>function jump(target, options) {
    var start = window.pageYOffset;

    var opt = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    };

    var distance = typeof target === 'string' ? 
        opt.offset + document.querySelector(target).getBoundingClientRect().top : 
        target
    ;

    var duration = typeof opt.duration === 'function'
          ? opt.duration(distance)
          : opt.duration
    ;

    var 
        timeStart = null,
        timeElapsed
    ;

    requestAnimationFrame(loop);

    function loop(time) {
        if (timeStart === null)
            timeStart = time;

        timeElapsed = time - timeStart;

        window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration));

        if (timeElapsed         requestAnimationFrame(loop)
        else
            end();
    }

    function end() {
        window.scrollTo(0, start + distance);

        typeof opt.callback === 'function' && opt.callback();
        timeStart = null;
    }

    // ...

}
</code>

シンプルさとパフォーマンスの実裝とは別に、先ほど説明したCSSソリューションのもう1つの利點は、ブラウザのデフォルトスクロールを使用するときに経験される動作と一致することです。各ページジャンプはブラウザの履歴スタックに押し込まれ、対応するボタンでこれらのジャンプを前後に閲覧できます(ただし、少なくともFirefoxにはスムーズなスクロールはありません)。

私たちが書いたコードで(CSSサポートが利用できない場合、それをフォールバックスキームと考えることができます)、ブラウザの履歴に対するスクリプトの動作を考慮しませんでした。コンテキストとユースケースに応じて、これは興味深いものである場合とそうでない場合がありますが、スクリプトがデフォルトのスクロールエクスペリエンスを強化する必要があると考える場合、CSSのように一貫した動作を期待する必要があります。

ネイティブJavaScriptを使用した滑らかなスクロール上の

FAQ(FAQ)

ライブラリを使用せずにネイティブJavaScriptを使用してスムーズなスクロールを実現するにはどうすればよいですか?

ネイティブJavaScriptを使用して、ライブラリを使用せずにスムーズなスクロールを実現するのは非常に簡単です。 window.scrollToメソッドを使用して、behaviorオプションをsmoothに設定できます。このメソッドは、特定の回數でウィンドウ內のドキュメントをスクロールします。簡単な例を次に示します:

<code>import easeInOutQuad from './easing'

export default class Jump {
  jump(target, options = {}) {
    this.start = window.pageYOffset

    this.options = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    }

    this.distance = typeof target === 'string'
      ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
      : target

    this.duration = typeof this.options.duration === 'function'
      ? this.options.duration(this.distance)
      : this.options.duration

    requestAnimationFrame(time => this._loop(time))
  }

  _loop(time) {
    if(!this.timeStart) {
      this.timeStart = time
    }

    this.timeElapsed = time - this.timeStart
    this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

    window.scrollTo(0, this.next)

    this.timeElapsed       ? requestAnimationFrame(time => this._loop(time))
      : this._end()
  }

  _end() {
    window.scrollTo(0, this.start + this.distance)

    typeof this.options.callback === 'function' && this.options.callback()
    this.timeStart = false
  }
}
</code>
この例では、クラス

の要素をクリックすると、ページは上部にスムーズにスクロールします。 your-element

なぜ私の滑らかなスクロールがSafariで機能しないのですか?

メソッドを使用して

オプションを設定して

オプションを設定しているscrollToサファリではサポートされていません。それを機能させるには、behaviorなどのポリフィルを使用できます。これにより、ネイティブにサポートしていないブラウザのスムーズなスクロールが可能になります。 smooth smoothscroll-polyfill特定の要素にスムーズにスクロールする方法は?

特定の要素にスムーズにスクロールするには、

メソッドを使用して、

オプションをElement.scrollIntoViewに設定できます。例は次のとおりです。behavior smooth この例では、クラス

の要素をクリックすると、ページはクラス
<code>var jump = (function() {

    var o = {

        jump: function(target, options) {
            this.start = window.pageYOffset

            this.options = {
              duration: options.duration,
              offset: options.offset || 0,
              callback: options.callback,
              easing: options.easing || easeInOutQuad
            }

            this.distance = typeof target === 'string'
              ? this.options.offset + document.querySelector(target).getBoundingClientRect().top
              : target

            this.duration = typeof this.options.duration === 'function'
              ? this.options.duration(this.distance)
              : this.options.duration

            requestAnimationFrame(_loop)
        },

        _loop: function(time) {
            if(!this.timeStart) {
              this.timeStart = time
            }

            this.timeElapsed = time - this.timeStart
            this.next = this.options.easing(this.timeElapsed, this.start, this.distance, this.duration)

            window.scrollTo(0, this.next)

            this.timeElapsed               ? requestAnimationFrame(_loop)
              : this._end()
        },

        _end: function() {
            window.scrollTo(0, this.start + this.distance)

            typeof this.options.callback === 'function' && this.options.callback()
            this.timeStart = false
        }

    };

    var _loop = o._loop.bind(o);

    // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
    function easeInOutQuad(t, b, c, d)  {
        t /= d / 2
        if(t         t--
        return -c / 2 * (t * (t - 2) - 1) + b
    }

    return o;

})();
</code>
の要素にスムーズにスクロールします。

your-element滑らかなスクロールの速度を制御できますか? target-element

ブラウザによって処理されるため、滑らかなスクロールの速度を直接制御することはできません。ただし、

を使用して、速度を含むスクロールアニメーションをより適切に制御するために、カスタムスムーズなスクロール機能を作成できます。

水平方向の滑らかなスクロールを実現するにはどうすればよいですか? window.requestAnimationFrame

垂直滑らかなスクロールと同様の方法で水平滑らかなスクロールを実現できます。また、

および

メソッドは、スクロールする水平位置を指定するための

オプションも受け入れます。例は次のとおりです。window.scrollTo Element.scrollIntoView leftこれにより、ドキュメントが右に100ピクセルをスムーズにスクロールします。

<code>function jump(target, options) {
    var start = window.pageYOffset;

    var opt = {
      duration: options.duration,
      offset: options.offset || 0,
      callback: options.callback,
      easing: options.easing || easeInOutQuad
    };

    var distance = typeof target === 'string' ? 
        opt.offset + document.querySelector(target).getBoundingClientRect().top : 
        target
    ;

    var duration = typeof opt.duration === 'function'
          ? opt.duration(distance)
          : opt.duration
    ;

    var 
        timeStart = null,
        timeElapsed
    ;

    requestAnimationFrame(loop);

    function loop(time) {
        if (timeStart === null)
            timeStart = time;

        timeElapsed = time - timeStart;

        window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration));

        if (timeElapsed         requestAnimationFrame(loop)
        else
            end();
    }

    function end() {
        window.scrollTo(0, start + distance);

        typeof opt.callback === 'function' && opt.callback();
        timeStart = null;
    }

    // ...

}
</code>
滑らかなスクロールアニメーションを停止する方法は?

ブラウザによって処理されるため、滑らかなスクロールアニメーションを直接停止することはできません。ただし、カスタムスムーズなスクロール関數を使用している場合は、

を使用してアニメーションフレームをキャンセルしてアニメーションを停止できます。

固定ヘッダーで滑らかなスクロールを実現する方法は? window.cancelAnimationFrame

固定ヘッダーを使用した滑らかなスクロールを実現するには、ヘッダーの高さを考慮に入れるために、スクロール位置を調整する必要があります。これを行うには、ターゲットスクロール位置からヘッダーの高さを差し引くことができます。

アンカーリンクのスムーズなスクロールを実現する方法は?

アンカーリンク用のスムーズなスクロールを実現するには、イベントリスナーをリンクのクリックイベントに追加し、

メソッドを使用してターゲット要素にスムーズにスクロールできます。例は次のとおりです。

これにより、ページ上のすべてのアンカーリンクがターゲット要素にスムーズにスクロールされます。 Element.scrollIntoView

キーボードナビゲーションを使用してスムーズなスクロールを実現する方法は?

キーボードナビゲーションを使用してスムーズなスクロールを実現することは、キーボードイベントの傍受や手動スクロールドキュメントが必要であるため、より複雑です。これを行うには、イベントリスナーを

イベントに追加して、keydownメソッドを使用してドキュメントをスムーズにスクロールします。 window.scrollTo

スムーズなスクロール実裝の互換性をテストする方法は?

browserstackなどのオンラインツールを使用して、滑らかなスクロールの互換性をテストできます。これらのツールを使用すると、さまざまなブラウザやさまざまなデバイスでWebサイトをテストして、すべての環(huán)境で実裝が適切に機能するようにします。

以上がバニラJavaScriptにスムーズなスクロールを実裝する方法の詳細內容です。詳細については、PHP 中國語 Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當する法的責任を負いません。盜作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中國語版

SublimeText3 中國語版

中國語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java vs. JavaScript:混亂を解消します Java vs. JavaScript:混亂を解消します Jun 20, 2025 am 12:27 AM

JavaとJavaScriptは異なるプログラミング言語であり、それぞれ異なるアプリケーションシナリオに適しています。 Javaは大規(guī)模なエンタープライズおよびモバイルアプリケーション開発に使用されますが、JavaScriptは主にWebページ開発に使用されます。

JavaScriptコメント:短い説明 JavaScriptコメント:短い説明 Jun 19, 2025 am 12:40 AM

JavaScriptcommentsEareEssentialential-formaining、およびGuidingCodeexecution.1)single-linecommentseared forquickexplanations.2)多LinecommentsexplaincomplexlogiCorprovidededocumentation.3)clarifyspartsofcode.bestpractic

JSで日付と時間を操作する方法は? JSで日付と時間を操作する方法は? Jul 01, 2025 am 01:27 AM

JavaScriptで日付と時間を処理する場合は、次の點に注意する必要があります。1。日付オブジェクトを作成するには多くの方法があります。 ISO形式の文字列を使用して、互換性を確保することをお勧めします。 2。時間情報を取得および設定して、メソッドを設定でき、月は0から始まることに注意してください。 3.手動でのフォーマット日付には文字列が必要であり、サードパーティライブラリも使用できます。 4.ルクソンなどのタイムゾーンをサポートするライブラリを使用することをお勧めします。これらの重要なポイントを習得すると、一般的な間違いを効果的に回避できます。

なぜの下部にタグを配置する必要があるのですか? なぜの下部にタグを配置する必要があるのですか? Jul 02, 2025 am 01:22 AM

PLACSTHETTHETTHE BOTTOMOFABLOGPOSTORWEBPAGESERVESPAGESPORCICALPURPOSESESFORSEO、userexperience、andDesign.1.IthelpswithiobyAllowingseNStoAccessKeysword-relevanttagwithtagwithtagwithtagwithemaincontent.2.iTimrovesexperiencebyepingepintepepinedeeping

JavaScript vs. Java:開発者向けの包括的な比較 JavaScript vs. Java:開発者向けの包括的な比較 Jun 20, 2025 am 12:21 AM

javascriptispreferredforwebdevelopment、whilejavaisbetterforlge-scalebackendsystemsandroidapps.1)javascriptexcelsininintingtivewebexperiences withitsdynAmicnature anddommanipulation.2)javaofferstruntypyping-dobject-reientedpeatures

JavaScript:効率的なコーディングのためのデータ型の調査 JavaScript:効率的なコーディングのためのデータ型の調査 Jun 20, 2025 am 12:46 AM

javascripthassevenfundamentaldatypes:number、string、boolean、undefined、null、object、andsymbol.1)numberseadouble-precisionformat、有用であるため、有用性の高いものであるため、but-for-loating-pointarithmetic.2)ストリングリムムット、使用率が有用であること

DOMでのイベントの泡立ちとキャプチャとは何ですか? DOMでのイベントの泡立ちとキャプチャとは何ですか? Jul 02, 2025 am 01:19 AM

イベントキャプチャとバブルは、DOMのイベント伝播の2つの段階です。キャプチャは最上層からターゲット要素までであり、バブルはターゲット要素から上層までです。 1.イベントキャプチャは、AddEventListenerのUseCaptureパラメーターをTrueに設定することにより実裝されます。 2。イベントバブルはデフォルトの動作であり、UseCaptureはfalseに設定されているか、省略されます。 3。イベントの伝播を使用して、イベントの伝播を防ぐことができます。 4.イベントバブルは、動的なコンテンツ処理効率を改善するためにイベント委任をサポートします。 5.キャプチャを使用して、ロギングやエラー処理など、事前にイベントを傍受できます。これらの2つのフェーズを理解することは、タイミングとJavaScriptがユーザー操作にどのように反応するかを正確に制御するのに役立ちます。

JavaとJavaScriptの違いは何ですか? JavaとJavaScriptの違いは何ですか? Jun 17, 2025 am 09:17 AM

JavaとJavaScriptは、異なるプログラミング言語です。 1.Javaは、エンタープライズアプリケーションや大規(guī)模なシステムに適した、靜的に型付けされ、コンパイルされた言語です。 2。JavaScriptは動的なタイプと解釈された言語であり、主にWebインタラクションとフロントエンド開発に使用されます。

See all articles