どうもー。ご無沙汰です。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効かないんだよダメだろそれはとか思ってたけど、理由を調べてみたらなんとなく仕方ないなって思えてしまった。
ではでは。