web-dev-qa-db-ja.com

OS X Lion Safariで水平スクロールがスワイプバックジェスチャーをトリガーするのを防ぐ方法はありますか?

私はdiv要素で水平スクロールを使用するUIで作業しています(_overflow: scroll_を使用)。左にスクロールすることはできません。歴史をさかのぼってアニメーションを開始するからです。同様に、進むべきWebサイトがある場合、右にスクロールできません。

OS X LionのChromeなど、他のブラウザーでも正常に動作します。これは、スワイプで履歴に戻ることもできます。(開発中のある時点で、div Safariでも機能しました。スクロールを壊す可能性のあるイベントハンドラとhtmlを追加しましたが、何が変更を加えたのかわかりません。

理想的には、特定のdivをスクロールするときに(終了に達した場合でも)履歴を前後に移動しないようにします。

更新: jQuery.mousewheel を追加してみましたが、どういうわけか問題が修正されました。 (.mousewheel()に空のイベントハンドラをアタッチしただけです。)私はまだ決定的な答えを探しています。

50
Barum Rho

私は何日も解決策を探していました。私がこれまでに持っているのは、このプラグインです:

https://github.com/micho/jQuery.preventMacBackScroll

OSXのスクロールを無効にしましたChrome(OSX Safariで無効にする方法が見つかりませんでした)左と上にスクロールします。

私がそれが助けてくれることを願っています、見つけたバグでプロジェクトに貢献してください、またはSafariのこの迷惑な動作を無効にする方法を見つけた場合

9
micho

要素(たとえば、<div>)トラックパッドでスクロールするが、ブラウザが前のページに戻るのを防ぐには、ブラウザのデフォルトアクションを防ぐ必要があります。

これを行うには、要素のmousewheelイベントをリッスンします。要素のスクロールプロパティとイベントのdeltaX/Yプロパティを使用して、デフォルトアクションがゼロ未満または幅/高さを超えたときに、デフォルトアクションを防止および停止できます。

全体のスクロール操作を防止しているときに、デルタ情報を使用して手動でスクロールすることもできます。これにより、10ピクセルなどで停止するのではなく、実際にゼロに到達できます。

// Add the event listener which gets triggered when using the trackpad 
element.addEventListener('mousewheel', function(event) {
  // We don't want to scroll below zero or above the width and height 
  var maxX = this.scrollWidth - this.offsetWidth;
  var maxY = this.scrollHeight - this.offsetHeight;

  // If this event looks like it will scroll beyond the bounds of the element, prevent it and set the scroll to the boundary manually 
  if (this.scrollLeft + event.deltaX < 0 || 
     this.scrollLeft + event.deltaX > maxX || 
     this.scrollTop + event.deltaY < 0 || 
     this.scrollTop + event.deltaY > maxY) {

    event.preventDefault();

    // Manually set the scroll to the boundary
    this.scrollLeft = Math.max(0, Math.min(maxX, this.scrollLeft + event.deltaX));
    this.scrollTop = Math.max(0, Math.min(maxY, this.scrollTop + event.deltaY));
  }
}, false);

これは、Mac上のChrome、Safari、およびFirefoxで機能します。 IEではテストしていません。

このソリューションは、問題の要素にのみ影響し、ページの残りの部分は通常どおりに動作します。したがって、期待どおりにブラウザーを使用してページに戻ることができますが、エレメント内では、意図しないときに誤って戻ることはありません。

17
user835542

はい、デフォルトの動作(スワイプ、ピンチなど)を無効にするには、追加するだけです。

event.preventDefault();

あなたの場合、単純にtouchMoveリスナーを登録し、そこにpreventDefault()を使用します(関数「touchmove」で)。

element.addEventListener("touchmove", touchMove, false);
9
Les Nie

CSS3スタイルを調べます

-ms-touch-action: none;
touch-action: none;

これは、使用されているアプリがHTML5/CSS3対応ブラウザーでのみ期待される場合に、私にとって完璧に機能します。

2
NinjaKC

このコールバックを添付して、jQueryマウスホイールも使用しました。

onMousewheel: function(e, delta, deltaX, deltaY){
  e.preventDefault();
  $('leftElement').scrollLeft($('leftElement').scrollLeft() + deltaX); // leftElement =     container element I want to scroll left without going back/forward
  $('downElement').scrollTop($('downElement').scrollTop() - deltaY); // this was another element within the container element
}
1
mzpn

https://github.com/micho/jQuery.preventMacBackScroll の貯金箱michoによる投稿これをサファリとクロムの両方で可能にしました。また、左スクロールと右スクロールの両方で動作するようにしました。

(これはcoffeescriptに含まれています。申し訳ありませんが、javascriptに戻すのは難しくありません)

$(document).on 'ready', ->

# This code is only valid for Mac
if !navigator.userAgent.match(/Macintosh/)
    return

# Detect browsers
# http://stackoverflow.com/questions/5899783/detect-safari-using-jquery
is_chrome = navigator.userAgent.indexOf('Chrome') > -1
is_safari = navigator.userAgent.indexOf("Safari") > -1
is_firefox = navigator.userAgent.indexOf('Firefox') > -1

# Handle scroll events in Chrome, Safari, and Firefox
if is_chrome || is_safari || is_firefox

    $(window).on 'mousewheel', (event) ->
        dX = event.deltaX || event.originalEvent.deltaX
        dY = event.deltaY || event.originalEvent.deltaY

        # If none of the parents can be scrolled right when we try to scroll right
        prevent_right = dX > 0 && $(event.target)
            .parents().addBack()
                .filter ->
                    return this.scrollWidth - this.clientWidth != 0 &&
                     $(this).scrollLeft() < this.scrollWidth - this.clientWidth &&
                     ($(this).css('overflow-y') == 'scroll' || $(this).css('overflow-y') == 'auto')
                .length == 0

        # If none of the parents can be scrolled left when we try to scroll left
        prevent_left = dX < 0 && $(event.target)
            .parents().addBack()
                .filter ->
                    return $(this).scrollLeft() > 0
                .length == 0

        # If none of the parents can be scrolled up when we try to scroll up
        prevent_up = dY > 0 && !$(event.target)
            .parents().addBack()
                .filter ->
                    return $(this).scrollTop() > 0
                .length == 0

        # Prevent minute left and right scroll from messing up vertical scroll
        if (prevent_right || prevent_left) && Math.abs(dY) > 5 && !prevent_up
            return
        # Prevent futile scroll, which would trigger the Back/Next page event
        if prevent_left || prevent_up || prevent_right
            event.preventDefault()
0
Adler Faulkner