マウスによるスクロールやスマホのスワイプを制御するjs(passive: false)


どうもー。ご無沙汰です。Webデザイナーのレーウィンですよ。
今回はマウスやスワイプでのスクロールの禁止・解除の簡単なjsについて、今更ながら解説。
今更ではあるけど、個人的にわかりやすいのがなかったから、多分需要があると信じてる。

あれ・・・?スクロール禁止が効かない・・・!?

jQueryを使用したマウス・スワイプ制御を実装してみたものの、上手いこと動かない。
そこで、コンソールを見てみるとこんな警告が。

Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

ようするに、addEventListenerで追加したtouchmoveはpassive:trueで処理するよ。ちなみにpassive:trueだとpreventDefaultは無視するよ。
ってこと。
まあ、要するにpreventDefaultを使いたければpassive:falseにしろと。

jQueryを使用せず、addEventListenerで制御しましょう

jQuery内を解析してpassive:falseにするのは流石に手間、というか無理。
なので自分で書いてしまいましょう。

function scroll_control(event) {
	event.preventDefault();
}
function no_scroll(){
	document.addEventListener("mousewheel", scroll_control, {passive: false});
	document.addEventListener("touchmove", scroll_control, {passive: false});
}
function return_scroll(){
	document.removeEventListener("mousewheel", scroll_control, {passive: false});
	document.removeEventListener('touchmove', scroll_control, {passive: false});
}

簡単なものだけど。
no_scroll()を呼び出せばスクロール禁止。
return_scroll()を呼び出せばスクロール禁止してたのを再開できます。

~完~

補足

そもそもなんでGoogle様はpassive:trueにしたのよって疑問があると思うので、調べました。
まず、Google等のブラウザを提供している側の重要な課題の1つとして
「スクロールパフォーマンス」
がある。要するに、スワイプしてから実際スクロールが反映されるまでの速度にあたる。スワイプしてるのにページが動かなかったらストレスすごい出るよね。
で、このスクロールパフォーマンスについて、Googleはイベントリスナにpassive:trueを付けることで大幅に向上する仕組みを作った。「Passive Event Listeners」と呼ばれるもの。これが2016年5月25日のアップデートでgoogle chromeに追加された。
そもそも、スクロールパフォーマンスでネックになったのがPreventDefault。どういうことなのかというと・・・

2016年5月以前のブラウザ
指「スワイプしたわ」

ブラウザ「ちょっと待ってPreventDefaultがあったら禁止なんだ・・・えーっと・・・・よし!最後まで見たけどPreventDefaultはない!スクロールするわ!」

指「もっかいスワイプしたわ」

ブラウザ「ちょっと待ってPreventDefaultがあったら禁止なんだ・・・えーっと・・・・よし!最後まで見たけどPreventDefaultはない!スクロールするわ!」

俺「おせえ」

2016年5月以降のブラウザ
指「スワイプしたわ」

ブラウザ「passive:trueだからPreventDefaultとかあっても関係ねえ!スクロールするわ!」

俺「はえ~」

ってこと。
つまり、以前のブラウザだとスワイプする度にPreventDefaultあるかないか判定が発生してたから遅かったということ。これを解決するためにデフォルトでPreventDefaultを無効にしてしまえばスクロールパフォーマンスが向上するよねってこと。
だから、Passive Event Listenersのオンオフができるオプションを用意して、デフォルトではtrueにしておいて、スクロール禁止をしたい人は個別でfalseにしてねってことで対応したみたい。

最初はなんでデフォルトでpreventDefault効かないんだよダメだろそれはとか思ってたけど、理由を調べてみたらなんとなく仕方ないなって思えてしまった。

ではでは。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。名前及びコメントは必須項目、メールアドレス及びサイトURLは任意です。