web-dev-qa-db-ja.com

iPadのサファリ:スクロールを無効にし、バウンス効果?

私はブラウザベースのアプリに取り組んでおり、現在はiPadのサファリブラウザの開発とスタイリングを行っています。

IPadで2つのことを探しています:必要のないページの垂直スクロールを無効にするにはどうすればよいですか? &弾性バウンス効果を無効にするにはどうすればよいですか?

112
Adam

非常に古いiOSデバイス用に開発している場合を除き、この回答は適用されません...他のソリューションを参照してください


2011年の回答:iOS Safari内で実行されるweb/htmlアプリの場合、次のようなものが必要です

document.ontouchmove = function(event){
    event.preventDefault();
}

IOS 5の場合、次の点を考慮する必要があります。 iOS 5でdocument.ontouchmoveとスクロール

2014年9月更新:より徹底的なアプローチは、こちらにあります: https://github.com/luster-io/prevent-overscroll 。それと多くの便利なwebappアドバイスについては、 http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

2016年3月更新:最後のリンクはアクティブではなくなりました- https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobileを参照してください-web-checklist.html 代わりにアーカイブバージョン用。それを指摘してくれて@falsarellaに感謝します。

153
Oskar Austegard

Body/htmlの位置を固定に変更することもできます。

body,
html {
  position: fixed;
}
96
Ben Bos

最新のモバイルブラウザーでのスクロールを防ぐには、passive:falseを追加する必要があります。この解決策が見つかるまで、これを機能させるために髪を引き出していました。これは、インターネット上の他の場所で言及されているだけです。

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}
33

これを行うには、このjQueryコードスニペットを使用できます。

$(document).bind(
      'touchmove',
          function(e) {
            e.preventDefault();
          }
);

これにより、垂直スクロールと、ページで発生するバウンスバック効果がブロックされます。

overflow: scroll;
-webkit-overflow-scrolling: touch;

コンテナでは、要素内でバウンス効果を設定できます

ソース: http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/

4
user956584

私はこれが少しゲレンデ外であることを知っていますが、私はSwiffyを使用してFlashをインタラクティブなHTML5ゲームに変換しており、同じスクロールの問題に遭遇しましたが、有効な解決策は見つかりませんでした。

私が抱えていた問題は、Swiffyステージが画面全体を占有しているため、ロードされるとすぐにドキュメントのtouchmoveイベントがトリガーされないことでした。

同じイベントをSwiffyコンテナに追加しようとした場合、ステージがロードされるとすぐに置き換えられました。

最終的には、ステージ内のすべてのDIVにtouchmoveイベントを適用することで(むしろ面倒に)解決しました。これらのdivも絶えず変化するため、チェックし続ける必要がありました。

これが私の解決策であり、うまくいくようです。私と同じ解決策を見つけようとしている他の人にとって役立つことを願っています。

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}
4
Tom

解決策はどれも私にはうまくいきません。これが私のやり方です。

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }
2
angry kiwi

IPhoneでテスト済み。ターゲット要素コンテナでこのcssを使用するだけで、スクロール動作が変更され、指が画面から離れると停止します。

-webkit-overflow-scrolling: auto

https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling

2
user1021364

このJSソリューションを試す

var xStart, yStart = 0; 

document.addEventListener('touchstart', function(e) {
    xStart = e.touches[0].screenX;
    yStart = e.touches[0].screenY;
}); 

document.addEventListener('touchmove', function(e) {
    var xMovement = Math.abs(e.touches[0].screenX - xStart);
    var yMovement = Math.abs(e.touches[0].screenY - yStart);
    if((yMovement * 3) > xMovement) {
        e.preventDefault();
    }
});

タッチイベントリスナーをデタッチせずに、デフォルトのSafariスクロールとバウンスジェスチャを防ぎます。

2

WebアプリMyScriptを使用しており、実際に書く代わりに(iPadおよびタブレットで)体のスクロール/ドラッグに苦労している人のために:

<body touch-action="none" unresolved>

それは私のためにそれを修正しました。

1
Miro

スクロールを防ぐためにjsを使用できます:

let body = document.body;

let hideScroll = function(e) {
  e.preventDefault();
};

function toggleScroll (bool) {

  if (bool === true) {
    body.addEventListener("touchmove", hideScroll);
  } else {
    body.removeEventListener("touchmove", hideScroll);
  }
}

そして、モーダルを開始/閉じるときにtoggleScroll funcを実行/停止するだけではありません。

このようなtoggleScroll(true) / toggleScroll(false)

(これはiOS専用で、Androidは機能しません)

1
Vlad Novikov

webkitOverflowScrollingスタイルを切り替えるこのJSソリューションを試してください。ここでのコツは、このスタイルがオフになっていて、モバイルSafariが通常のスクロールに移行してオーバーバウンスを防ぐことです。残念ながら、進行中のドラッグをキャンセルすることはできません。この複雑なソリューションは、onscrollも追跡します。これは、頭上での跳ね返りにより、追跡可能なscrollTopが負になるためです。このソリューションはiOS 12.1.1でテストされ、単一の欠点があります。スクロールを加速すると、スタイルをリセットしてもすぐにキャンセルされないため、オーバーバウンドが発生します。

function preventScrollVerticalBounceEffect(container) {
  setTouchScroll(true) //!: enable before the first scroll attempt

  container.addEventListener("touchstart", onTouchStart)
  container.addEventListener("touchmove", onTouch, { passive: false })
  container.addEventListener("touchend", onTouchEnd)
  container.addEventListener("scroll", onScroll)

  function isTouchScroll() {
    return !!container.style.webkitOverflowScrolling
  }

  let prevScrollTop = 0, prevTouchY, opid = 0

  function setTouchScroll(on) {
    container.style.webkitOverflowScrolling = on ? "touch" : null

    //Hint: auto-enabling after a small pause makes the start
    // smoothly accelerated as required. After the pause the
    // scroll position is settled, and there is no delta to
    // make over-bounce by dragging the finger. But still,
    // accelerated content makes short single over-bounce
    // as acceleration may not be off instantly.

    const xopid = ++opid
    !on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)

    if(!on && container.scrollTop < 16)
      container.scrollTop = 0
    prevScrollTop = container.scrollTop
  }

  function isBounceOverTop() {
    const dY = container.scrollTop - prevScrollTop
    return dY < 0 && container.scrollTop < 16
  }

  function isBounceOverBottom(touchY) {
    const dY = touchY - prevTouchY

    //Hint: trying to bounce over the bottom, the finger moves
    // up the screen, thus Y becomes smaller. We prevent this.

    return dY < 0 && container.scrollHeight - 16 <=
      container.scrollTop + container.offsetHeight
  }

  function onTouchStart(e) {
    prevTouchY = e.touches[0].pageY
  }

  function onTouch(e) {
    const touchY = e.touches[0].pageY

    if(isBounceOverBottom(touchY)) {
      if(isTouchScroll())
        setTouchScroll(false)
      e.preventDefault()
    }

    prevTouchY = touchY
  }

  function onTouchEnd() {
    prevTouchY = undefined
  }

  function onScroll() {
    if(isTouchScroll() && isBounceOverTop()) {
      setTouchScroll(false)
    }
  }
}
1
Anton Baukin

ソリューションのテスト、iOS 12.xで動作

これは私が遭遇した問題です:

<body> <!-- the whole body can be scroll vertically -->
  <article>

    <my_gallery> <!-- some picture gallery, can be scroll horizontally -->
    </my_gallery>

  </article>
</body>

ギャラリーをスクロールしている間、体は常にスクロールします(人間のスワイプは実際には水平ではありません)。

ギャラリーがスクロールを開始している間に私がやったこと

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

そして、私のギャラリーがスクロールを終了すると...

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

これがお役に立てば幸いです〜

0
RRTW

IPadのサファリを削除するコード:スクロールを無効にし、バウンス効果

   document.addEventListener("touchmove", function (e) {
        e.preventDefault();
    }, { passive: false });

ドキュメント内にcanvasタグがある場合、いつかCanvas内のオブジェクトの使いやすさに影響します(例:オブジェクトの移動)。以下のコードを追加して修正してください。

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
        e.stopPropagation();
    }, { passive: false });
0
Teju V B

改善された回答@Ben Bosと@Timによるコメント

このCSSは、位置の変更/幅と高さのないわずかな遅れのため、CSS再レンダリングのスクロールとパフォーマンスの問題を防ぐのに役立ちます

body,
html {
  position: fixed;
  width: 100%; 
  height: 100%
}

0
auronsan zenx