有什么方法可以阻止水平滚动触发OS X Lion Safari上的向后滑动手势?

时间:2012-01-05 04:36:42

标签: javascript macos safari

我正在使用div元素中使用水平滚动的UI(使用overflow: scroll)。我无法向左滚动,因为它会启动动画以便返回历史记录。同样,当有一个网站可以向前滚动时,我无法向右滚动。

它适用于其他浏览器,包括OS X Lion上的Chrome,它也支持刷回历史记录。 (在我开发的同时,在div中滚动也在Safari上工作。我添加了事件处理程序和html,这可能会破坏滚动,但我不知道是什么让它发生了变化。)

理想情况下,我希望在特定div上滚动时阻止在历史记录中返回或转发(即使它已经结束。)

更新:我尝试添加jQuery.mousewheel,它以某种方式解决了问题。 (我只是在.mousewheel()附加了一个空的事件处理程序。)我仍在寻找明确的答案。

8 个答案:

答案 0 :(得分:16)

为了允许元素(例如<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上测试过。

此解决方案仅影响相关元素,并使页面的其余部分正常运行。因此,您可以按预期使用浏览器并返回页面,但在元素内部,您不会意外地返回,但并不意味着。

答案 1 :(得分:9)

是的,为了禁用默认行为(滑动,捏合等),您只需要添加:

event.preventDefault();

在你的情况下,只需注册touchMove监听器并在那里使用preventDefault()(在函数“touchmove”中)。

element.addEventListener("touchmove", touchMove, false);

答案 2 :(得分:8)

我一直在寻找解决方案。到目前为止我所拥有的是这个插件:

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

当您向左和向上滚动时,它禁用了OSX Chrome的滚动(我无法找到为OSX Safari禁用它的方法)。

我希望有所帮助,请为您找到的任何错误贡献给项目,或者如果您找到一种方法来禁用Safari的烦人行为

答案 3 :(得分:2)

了解CSS3风格

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

当所使用的应用程序仅适用于支持HTML5 / CSS3的浏览器时,这对我来说非常有用。

答案 4 :(得分:1)

我还使用了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
}

答案 5 :(得分:1)

从用户的角度来看,我是在搜索相同内容时来到这里的。因此,这是会影响到此的FF设置:

browser.gesture.swipe.left
browser.gesture.swipe.right

将它们设置为空字符串(删除其中的内容)

来源:https://forums.macrumors.com/threads/disabling-firefox-back-forward-from-horizontal-scrolling.111589/

答案 6 :(得分:1)

在现代浏览器中,这应该可以解决问题:

element.addEventListener("wheel", function(event) {
  if (Math.abs(event.deltaX) < Math.abs(event.deltaY)) {
    // Scrolling more vertically than horizontally. Let it be!
    return
  }
  const scrollLeftMax = this.scrollWidth - this.offsetWidth
  if (
    this.scrollLeft + event.deltaX < 0 ||
    this.scrollLeft + event.deltaX > scrollLeftMax
  ) { 
    event.preventDefault()
  }
}, false)

旁注:Firefox具有handy scrollLeftMax property, but it's not standard,因此最好自己计算。

答案 7 :(得分:0)

由micho发布的https://github.com/micho/jQuery.preventMacBackScroll的小猪退出我已经在野生动物园和铬中实现了这一点。此外,我使它适用于左滚动和右滚动。

(很抱歉这是在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()