Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8816

iOSでWebページの一部要素のみスクロール可能にする

$
0
0

背景

PC や Android など、iOS 以外のデバイスで、ページ全体をスクロール無効にし、それ以外の要素は有効にしたい場合は、以下の CSS を追加すれば良いです。
(中略)
しかし、iOS では、この方法だとうまくいきません。

実現したいこと

ページ全体をスクロール禁止にした上で、スクロール可能な要素についてのみ内部の(子要素を含む)どこをタッチしてもスクロールする。
overflow:scrollに設定されていても子要素が少なくスクロール可能状態になっていない要素や、スクロール可能状態だが一番下までスクロールされきっており
(諸事情によりwindowやbodyではなく、自分で作成した一番上位の要素をrootElementとして、これにイベントを設定する仕様になっている)

実現方法

  • 再帰的に親要素を辿ってスクロール可能要素があるか確認する関数を作成
constcheck=(elem:HTMLElement,rootID:string):boolean=>{elem.scrollBy({top:1});if(elem?.id==rootID){returnfalse;}elseif(elem.scrollTop){if(elem.scrollTop>1)elem.scrollBy({top:-1});returntrue;}elseif(elem.parentElement){returncheck(elem.parentElement);}else{returnfalse;}};
  • スクロール可能な要素がなければpreventDefaultする関数を作成
constpreventScroll(rootElement:HtmlElement)=>{rootElement.addEventListener('touchmove',e=>{constelem=e.targetasHTMLElement;if(!(elem&&check(elem,rootElement.id))&&e.cancelable)e.preventDefault();},{passive:false});});
  • スクロールを禁止したい要素に適用(ここでは仮称globalContainerに適用)
constroot=document.getElementById("globalContainer");if(root)preventScroll(root)

備考

check()内で一度スクロールを試みた後、スクロール可能な要素と判定された場合最初にスクロールを試みた分を戻しているが、

constcheck=(elem:HTMLElement,rootID:string):boolean=>{elem.scrollBy({top:1});    (中略)elseif(elem.scrollTop){if(elem.scrollTop>1)elem.scrollBy({top:-1});returntrue;}

これによりスクロール可能要素が最後までスクロールしきった状態にならず、スクロールしきった要素を引っ張って画面全体がスクロールされる仕様に対処している。

まとめ

力押しの判定方法で目標を実現した。
また、e.targetをHTMLElementにキャストしている部分や備考で示した箇所の記述など、確実に正しい記述である自信がない部分も多いため、指摘歓迎。

参考


Viewing all articles
Browse latest Browse all 8816

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>