37423


次のコードを実行してみて、スクロールバーを動かす速さによってコールバックが呼ばれる回数が異なることを知りました。（速ければ少なく、遅ければ多い）

[code]

    window.onscroll = () => {
        console.log("scrolled");
    };
    
[/code]

スクロールイベントはどのような条件が揃うと発火するのでしょうか？

[scroll - Event reference | MDN](https://developer.mozilla.org/en-
US/docs/Web/Events/scroll)などにも条件については書かれていないようです。


CC BY-SA 3.0
2017-08-22T12:11:00.910
37404
2017-08-23T01:10:27.660
13199
question
javascript dom
scrollイベントはいつ発火する？


# 実装依存

結論からいえば、実装依存ではないかと思います。

  * [4.4.2.1. wheel - UI Events （日本語訳）](https://triple-underscore.github.io/uievents-ja.html#event-type-wheel)

> 注記： UA や入力装置によっては、ホイールが回される速度もデルタ値に影響し得る — 高速になる程 高いデルタ値を生産するように。

# スクロール処理

  * [12.2. スクロール処理 - CSSOM View Module （日本語訳）](https://triple-underscore.github.io/cssom-view-ja.html#scrolling-events)
  * [12.2. Scrolling - CSSOM View Module](https://drafts.csswg.org/cssom-view/#scrolling-events)

# 検証

手元の環境で検証した限りでは、`scroll` イベントは `wheel` イベント、`keydown` イベントと連動して発火しているように見えます。  
キーボードで同じキーを押し続けた場合、`keydown` イベントも連続して発火するのが一般的なWebブラウザの動作のようですが、 **keydown
イベントの発火回数はキーを押し続けた時間に比例します** 。  
`wheel` イベントも同じなのでしょう。

  * [PageDown] キーを1回押下 -> `keydown`, `scroll` イベントが1回発火する
  * [↓] キーを押し続ける -> 「`keydown` -> `scroll`」の順序で同イベントが連続して同じ回数だけ発火する
  * マウスホイールで下スクロールし続ける -> 「`wheel` -> `scroll`」の順序で同イベントが連続して同じ回数だけ発火する

[code]

    'use strict';
    addEventListener('scroll', function (event) {
      console.log(event.type);
    }, false);
    
    addEventListener('keydown', function (event) {
      console.log(event.type);
    }, false);
    
    addEventListener('wheel', function (event) {
      console.log(event.type);
    }, false);
[/code]

[code]

    body {
     height: 10000px;
     color: black;
     background-color: #eef;
    }
[/code]

[code]

    <p>sample</p>
[/code]

Re: @letrec


CC BY-SA 3.0
2017-08-22T15:17:02.707
37413
2017-08-22T15:17:02.707
20262
37404
answer


おおざっぱに言うと、暇なときにイベントが発火します。1つの要素に対して複数のイベントが溜まることはありません。

規格にのっとって説明すると([12.2. Scrolling](https://drafts.csswg.org/cssom-
view/#scrolling-events))、ブラウザがスクロール処理を行うとスクロールした要素が pending scroll event
targets に溜められます。すでに要素が pending scroll event targets
に入っている場合は何もしません。このため、どんなにたくさんスクロールしても、後述の処理が始まるまでは最大1つの `scroll`イベントしか予約されません。

[イベントループに入ったときに、run the scroll steps
が起動](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-
processing-model:run-the-scroll-steps)され、pending scroll event targets に対して
`scroll` イベントを発火します。  
ただし、scroll イベントハンドラはページを重くする要因となっていることが多いので、実際のブラウザではイベントループで毎回 run the scroll
steps を起動していないかもしれません。


CC BY-SA 3.0
2017-08-23T01:10:27.660
37423
2017-08-23T01:10:27.660
3475
37404
answer