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

Bar*_*Rho 50 javascript safari macos

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

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

理想情况下,我想阻止在特定时滚动历史记录div(即使它已经结束).

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

use*_*542 17

为了允许元素(例如a <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);
Run Code Online (Sandbox Code Playgroud)

这适用于Mac上的Chrome,Safari和Firefox.我没有在IE上测试过.

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


mic*_*cho 11

我一直在寻找解决方案.到目前为止我在这个插件中有:

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

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

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

  • ^就像因为您没有使用他的解决问题方法而给您打分的老师一样。 (3认同)
  • 我明确投了赞成票以覆盖@DiligentKeyPresser 的反对票。发帖者没有要求普通的 js 解决方案。我很欣赏 micho 为开发解决方案所做的努力,并将其发布在这里,以造福所有人。 (2认同)

Les*_*Nie 9

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

event.preventDefault();
Run Code Online (Sandbox Code Playgroud)

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

element.addEventListener("touchmove", touchMove, false);
Run Code Online (Sandbox Code Playgroud)

  • 没问题:)也许别人会从这个答案中受益.这不仅仅是jQuery方法<https://developer.mozilla.org/en/DOM/event.preventDefault>.使用它可以禁用任何事件的默认行为,不仅适用于我的示例中的touchmove.你试过吗? (7认同)

Tad*_*spy 5

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

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)
Run Code Online (Sandbox Code Playgroud)

旁注:Firefox 有一个方便的scrollLeftMax属性,但它不是标准的,所以最好自己计算一下。