ipad safari:スクロールを無効にし、バウンス効果?


126

私はブラウザーベースのアプリを開発しています。現在、ipad safariブラウザーの開発とスタイリングを行っています。

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


私のために働いたと(現在で一つだけ、以下の回答を参照してくださいstackoverflow.com/a/51176339/1979180
frage

回答:


157

非常に古いiOSデバイス用に開発しているのでない限り、この回答は適用されなくなりました...他のソリューションを参照してください


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

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

iOS 5の場合、次のことを考慮に入れることができます:document.ontouchmoveおよびiOS 5でのスクロール

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に感謝します。


1
iOS Safari内でwebappを実行していて、ontouchmoveイベントを無効にしてみましたが、慎重に行った場合でもバウンス効果を確認できます。(iOS 5)
Nilesh

7
バウンス効果を無効にするだけではどうですか...?
Yuval A.

6
このアプローチの問題は、dom内のスクロール可能なdivがもうスクロールしないことです。domの設定によっては、これを回避する方法があります。
huesforalice 2014年

3
これを使用しているときにdivをスクロールするonTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } ことについて質問する人がたくさんいます。そうすると、それらのdivをスクロール可能にするには、追加します。これにより、イベントが本文にぶつからないようにしますが、本文は弾力性がありません。編集:これは$( 'div')。on( 'touchmove'、... onTouchMove);を設定することを前提としています。
Matt Kenefick、2014

1
:@OskarAustegard最後のリンクは私のために仕事をしませんでしたが、私は、Webアーカイブのコンテンツを見つけることができるweb.archive.org/web/20151103001838/http://www.luster.io/blog/...
falsarella

116

body / htmlの位置をfixedに変更することもできます:

body,
html {
  position: fixed;
}

2
これは実際にはiPad iOS 8.2 Safariで非常にうまく機能しました。バウンス効果はなくなりました。
AkseliPalén15年

3
これまでに見たことのある最善の方法
ヒルデンデ2015年

8
絶対位置とすべての辺を0に設定して(フルスクリーンのdivを作成するため)何かを配置したい場合は機能しません-ドキュメント全体が縮小されません。
2015年

4
これを使用すると、ページがページの先頭に戻り、入力に集中します。これを回避する方法を知っていますか?
ジュリー、

1
@riv追加幅:100%; 高さ:本文とhtmlの両方で100%が役立ちました。
Tim

57

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

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

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


7
{ passive: false }それなしでは確実に動作しません!!! StackOverflowデュードへようこそ
Ser

2
このソリューションを提供していただきありがとうございます。
ポールZ.

6
これが正解です。説明はこちらで確認できます:developer.mozilla.org/en-US/docs/Web/API/EventTarget/…Chrome 54のtouchmoveがデフォルトでpassiveにtrueになった後、preventDefaultの呼び出しは無視されます。そのため、{passive:false}を渡す必要があるため、preventDefault呼び出しは無視されません。
derickito

1
あなたはJSで関数を宣言しています-しかし、この関数を要素でどのように呼び出して、提案どおりに機能するのですか?
ikwyl6

4
これは、あらゆる種類のスクロールを無効にする場合に最適です。しかし、本体のスクロールを無効にし、要素をスクロールする可能性を維持したい場合はどうなりoverflow-y: scrollますか?たとえば、ボディよりもビューの高さが高いモーダルがあるとします。
Calsal

7

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

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

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


11
これはJavascriptではなく、jQueryです。誰もがそのフレームワークを使用しているわけではないことを述べておく必要があります。
2014

水平方向のバウンスまたはスクロールを停止する方法
fidel castro

横スクロールでは、cssだけでそれを無効にして、overflow-x:hiddenを適用することもできます。あなたのメインコンテナに。Safariの最新バージョンでは、バウンス効果を無効にすることはできません。これは、モバイルデバイスのブラウザーのネイティブ機能です。
アレッサンドロインカ

6
@intaただ言うと、これは実際にはJavaScriptです。それは純粋なJavaScriptではありません。
ベンロランティ2017年

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

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

出典:http : //www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/


1
一緒overflow:hidden<body>、これはまだ最適なソリューションです。ただし、キーボードを開いたり、画面の下部をスライドすると、機能しなくなります。
Fabian von Ellerts

入力onfocus除去オーバーフローを試してください
user956584

4

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

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

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

結局、ステージ内のすべてのDIVにtouchmoveイベントを適用することで(むしろ乱雑に)解決しました。これらのdivも常に変化しているので、私はそれらをチェックし続ける必要がありました。

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

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

これにより、iPadでスクロール全体が無効になります
fidel castro

3

ipad safariを削除するコード:スクロールを無効にして、バウンス効果

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

あなたが持っている場合はキャンバス(例:被写体の動き)タグ内のドキュメントを、いつかそれがキャンバス内のオブジェクトの使いやすさに影響を与えます。以下のコードを追加して修正してください。

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

2

この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スクロールとバウンスジェスチャーを防止します。


これにより、Webアプリがbody要素を完全にスクロールしなくなります。
MartijnICU 2016年

2

解決策のどれも私のために機能しません。これが私のやり方です。

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

.the_element_that_you_want_to_have_scrolling {scrolling:touch; }
ロイSEGALL

あなたの答えはhtml、bodyではうまくいきましたが、「the_element_that_you_want_to_have_scrolling」でスクロールできません。この要素は、ボディの下にあるいくつかのdiv内にネストされています。このネストされたdivに、スクロールさせたい典型的な要素タグのどれが重要か?私には相対的な立場があります。
ikwyl6


1

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

<body touch-action="none" unresolved>

これで解決しました。


1

あなたはスクロールを防ぐために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モーダルをopnen / closeするときにfuncを実行/停止するだけではあり ません。

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

(これはiOSのみで、Androidでは機能しません)


1

webkitOverflowScrollingスタイルを切り替えるこのJSソリューションを試してください。ここでの秘訣は、このスタイルがオフであり、モバイルSafariが通常のスクロールに移行してオーバーバウンスを防ぐことです。残念ながら、進行中のドラッグをキャンセルすることはできません。この複雑なソリューションonscrollは、上からの跳ね返りscrollTopが追跡可能なネガティブになると追跡します。このソリューションはiOS 12.1.1でテストされましたが、欠点が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

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

このCSSは、幅と高さなしで位置が変化した/少し遅れているため、CSSの再レンダリングによるスクロールとパフォーマンスの問題を防ぐのに役立ちます

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


IOS13では、これは私にとって最もクリーンなソリューションであり、まだ欠点は見つかりません...
Soylent Graham

0

跳ね返りを解消したくないが、いつ停止するかを知りたい場合(たとえば、画面距離の計算を開始する場合)は、次の操作を実行できます(コンテナーはオーバーフローしているコンテナー要素です)。

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight


-1

怒っているキウイと同様に、位置ではなく高さを使用して動作させました:

html,body {
  height: 100%;
  overflow: hidden;
}

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}

文書として、これは運動量が無効にならない後もバウンスを有効にします
CaSUaL

@CaSUaLどういう意味かわからない?このソリューションは私のユースケースで機能しました...
austinh7 '29

-1

テスト済みのソリューション、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;}

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.