任何防止水平滚动触发OS X Lion Safari向后滑动手势的方法

Any way to prevent horizontal scrolling triggering swipe back gesture on OS X Lion Safari?

本文关键字:方法 Safari Lion 滚动 水平 止水 OS 任何防      更新时间:2023-09-26

我正在开发一个在div元素中使用水平滚动的UI(使用overflow: scroll)。我不能向左滚动,因为这会启动动画,让它回到历史。同样,当有网站可供访问时,我无法向右滚动。

它在其他浏览器上运行良好,包括OS X Lion上的Chrome浏览器,该浏览器也支持滑动以追溯历史。(在我开发的时候,div中的滚动在Safari上也起到了作用。我添加了事件处理程序和html,这可能会破坏滚动,但我不知道是什么改变了它。)

理想情况下,当在特定的div上滚动时(即使它已经结束),我希望防止在历史中倒退或前进

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

为了允许元素(例如<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.

此解决方案只会影响有问题的元素,并使页面的其余部分正常工作。因此,您可以按预期使用浏览器并返回页面,但在元素内部时,您不会无意中返回。

我几天来一直在寻找解决方案。到目前为止,我在这个插件中有:

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

当你向左和向上滚动时,它禁用了OSX Chrome的滚动(我找不到在OSX Safari中禁用它的方法)。

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

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

event.preventDefault();

在您的情况下,只需注册touchMove侦听器并在那里使用preventDefault()(在函数"touchMove"中)。

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

在现代浏览器中,这应该可以做到:

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有一个方便的scrollLeftMax属性,但它不是标准的,所以最好自己计算。

查看CSS3样式的

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

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

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

小猪后退https://github.com/micho/jQuery.preventMacBackScroll由micho发布我已经使这在safari和chrome中成为可能。此外,我让它同时适用于左滚动和右滚动。

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

我是从用户的角度搜索相同内容时来到这里的。下面是影响这一点的FF设置:

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

将它们设置为空字符串(删除现有内容)

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