5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【モーダルなどの一時スクロール禁止】スクロールジャンクとは?

Last updated at Posted at 2019-07-08

##やりたいこと
モーダルを開いたときに、「パソコンのスクロールを一時的止めたいな」
と思うことがありました。
とりあえずかいてみました。

window.addEventListener('mousewheel',(e)=>{
   e.preventDefault();
});

preventDefaulでスクロールの動きを封じるやつです。
でもエラーが出て全然動きません。

##スクロールジャンク防止が原因だった
↓こちらのサイトでスクロールジャンクを知りました。
https://blog.webico.work/passive-event-listeber01

どうやら、スクロール系のイベント(mousewheel,touchmove,wheelなど)は、
スクロールするたびに登録された全てのイベントにpreventDefault()がないか確認が終わるまで処理が行えないそうです。これが所謂スクロールジャンク。

それを防ぐためにaddEventListenerにはpassive:trueという値が初期値で設定されています。
これは実行前に、「preventDefault()実行しませんよ〜」と明示するものらしいです。

でも!
今回はprevcentDefault()を実行するので、ここの値をいじります。

##解決方法は?
passiveにfalseを渡してあげましょう。

window.addEventListener('mousewheel',(e)=>{
e.preventDefault();},{passive:false});

ちょっと待って!
昨日調べたことによると、イベントリスナの第三引数はuseCaptureというイベント伝播に関する引数だったはず...

##addEventListenerの第三引数の謎
https://qiita.com/kozy4324/items/85831e2c990d92b8397b
こちらの記事に答えがありました。
元々はuseCaptureのみだったみたいですが、拡張されたようです。現在では

element.addEventListener('click',Handler(),{
   once: true,
   passive: true,
   capture: true
});

と書けるとのこと。
(以前の書き方と互換性があり、第三引数にboolean型のみ渡した場合はcaptureの値として判断されるそうです。)

###onceってなに?
onceにすると、イベントハンドラが一度だけ処理されます。
一度しか読み込まないイベントを明示することで、メモリの節約になる!ってことですね。
毎回removeEventListenerを使うより随分楽ですね。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?