【问题标题】:Stop chrome back/forward two finger swipe停止 chrome 后退/前进两指轻扫
【发布时间】:2013-03-27 14:06:25
【问题描述】:

我想禁用导致 Chrome 后退或前进的两指滑动。 我有一个网站,如果用户不专门保存,用户可能会失去工作进度。

我尝试过使用window.onbeforeunload,但如果我在 url 中有哈希值,这似乎不起作用(后退会在 www.example.com/work/#step1#unsaved www.example.com/work 之间改变/#step0) 并且事件似乎没有触发。

我正要切换到另一个解决方案,但今天我注意到在 Google Docs 中它已完全禁用。他们是如何做到的?

【问题讨论】:

  • window.onbeforeunload 需要同步任务。也许这就是这种方法的问题。
  • 您可以使用onhashchange 事件来检测何时滑动尝试更改没有?

标签: javascript google-chrome swipe


【解决方案1】:

Disable Chrome two fingers back/forward swipe

这对我有用:

body {
  overscroll-behavior-x: none;
}

【讨论】:

  • 如果这对您不起作用,请尝试在 html 元素上指定 overscroll-behavior-x
  • 谢谢@Matt Sanders,这太棒了,水平滚动有时很容易触发这个手势
  • 很高兴它有帮助!
  • 半离题,但值得注意的是,这也适用于其他元素。如果您想在整个页面上保持两指滑动,但又想对具有水平滚动的特定部分禁用它,这尤其有用。
【解决方案2】:

默认情况下使特定页面在新选项卡/窗口中打开(通过将 target="_blank"> 放入超链接)。这样就没有前一页可以返回了。

或者默认阻止水平滚动。为此,您可以使用 jquery.mousewheel 来做:

$(document).on("mousewheel",function(event,delta){ 
  // prevent horizontal scrolling
  if (event.originalEvent.wheelDeltaX !== 0) {
    event.preventDefault();
  } 
});

【讨论】:

  • 最好使用“event.stopPropagation()”
  • @sheerun 不,不是。 stopPropagation 杀死可能导致依赖于这些事件被触发的第三方代码中的意外行为和错误的事件。总是更喜欢 preventDefault。此外,在 Chrome 59.0.3071.115 中,preventDefault 似乎不再适用于这种情况(stopPropagation 也没有)。有没有人可以解决这个问题?
  • 是的,刚刚在 Chrome 60 D 上被这个咬了:
【解决方案3】:

假设您有一个水平滚动元素,添加overscroll-behavior-x: contain; 是防止滚动动作溢出到页面并导致导航的最简单方法。

https://dev.to/danburzo/css-micro-tip-prevent-history-navigation-on-horizontally-scrolling-elements-3iil

https://caniuse.com/#feat=css-overscroll-behavior

【讨论】:

  • 这似乎并不能阻止在 Windows 中的 Chrome 上水平滚动时发生后退导航。编辑:当属性位于html 标签而不是可滚动容器时,显然是有效的。
【解决方案4】:

禁用或替换 Google Chrome 61 的滑动手势

将我带到这里的问题被标记为“重复”并且无法回答。我相信这个答案更适合“重复”的问题,但是,我觉得这个答案可能会为任何一个问题的人节省时间。

更好的问题: Disable navigation swipe on Chrome browser in javascript

这篇 Google 开发者文章帮助我允许 e.preventDefault() 从 Chrome 61 开始工作并防止滑动手势。

https://developers.google.com/web/updates/2017/01/scrolling-intervention

givanse 对以下问题的回答是我用来编写自己的滑动事件处理程序的代码:

Detect a finger swipe through JavaScript on the iPhone and Android

综上所述,以下两个事件用于实现滑动手势:

handleTouchStart (e) {
  ...
},
handleTouchMove (e) {
  ...
  e.preventDefault()
}

从 Chrome 56 开始,默认行为是使事件侦听器处于被动状态,从而禁用阻止 Chrome 滑动手势的功能。要覆盖此行为,可以按如下方式添加事件侦听器:

document.addEventListener(
  'touchstart',
  this.handleTouchStart,
  {passive: false}
)
document.addEventListener(
  'touchmove',
  this.handleTouchMove,
  {passive: false}
)

通过将 {passive: false} 对象作为第三个参数传递给 addEventListener 方法,监听器被注册为活动的并且可以使用 e.preventDefault() 事件方法停止 Chrome 的默认行为。

【讨论】:

    【解决方案5】:

    我一直在做类似的事情,我想覆盖向前/向后历史滑动手势。根据您的滑动区域,您可以按如下方式调整选择器:

    html { touch-action:none; }
    

    这是相关文档,它为您提供所有触摸操作的所有属性,例如浏览器内置的平移或缩放功能。

    https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

    【讨论】:

    • 在 chrome 中没有帮助我。
    【解决方案6】:

    在@roy riojas 和@redgetan 之前给出的答案的基础上 - 我结合了他们的答案,以允许这是动态的,并防止向前和向后 - 再次 - 每个 @roy 的 cmets - 你必须知道你的班级元素,对于这个实现 - 实际被滚动的嵌套元素的类

    (function ($) {
      $(document).on('mousewheel', function(e) { 
        var $target = $(e.target).closest('.scrollable-h');
        var scroll = $target.scrollLeft();
        var maxScroll = $target.find('.scrollable-h-content').width() - $target.width();
    
        if(scroll <= 0) {
          if(scroll <= 0 && e.originalEvent.wheelDeltaX >= 0) {
            e.preventDefault();
          }
        }
        if(scroll >= maxScroll) {
          if (scroll >1 && e.originalEvent.wheelDeltaX <= 0) {
            e.preventDefault();
          }
        }
    });}(jQuery));
    

    【讨论】:

      【解决方案7】:

      我可以通过在地址栏中键入 chrome://flags 并向下转到“Overscroll history navigation”并从下拉菜单中将其设置为“Disabled”来禁用它。

      【讨论】:

      • 这对我不起作用。 Windows 10 Chrome v91
      【解决方案8】:

      您好,这在 chrome 上对我有用,但不适用于整个页面,但适用于我有可滚动内容的地方。

      在 Google Docs(电子表格)中,它似乎可以正常工作,因为它们没有后页可走。如果您(手动)导航到另一个 URL,它不会阻止您返回。

      $(document).on('mousewheel', function(e) { 
        var $target = $(e.target).closest('.scrollable-h');
        if ($target.scrollLeft () <= 4) {
          $target.scrollLeft(5);
          return false;
        }
      });
      

      要记住的一点是,上面的代码做了两个假设:

      1. 具有水平滚动内容的元素有一个类scrollable-h
      2. If 检查 scrollLeft 是否大于 4px,然后让它滚动到 5px 返回 false 有效地取消了后退手势

      重要: - 这只会防止向后滑动手势,当快速完成时,如果你做得非常慢,它有时仍会触发。

      • 此外,这不会阻止向前滑动手势,但也可以通过检查元素是否已达到最大 scrollLeft 来完成。如果是这种情况,则将其向后移动 20 像素并返回 false 以防止事件发生...如果它恰好对您有意义,则由您来添加此用例。

      您可以在此处查看概念证明。 http://jsfiddle.net/royriojas/JVA6m/#base

      【讨论】:

      • 那么如何防止反弹呢?似乎检测我们是否处于边缘的唯一方法是在滚动发生之后,而不是之前
      • @KevinNewman 我非常感谢你。我花了很多时间试图弄清楚为什么wheel 事件中的preventDefault 对我不起作用。但后来我注意到你评论中的“反弹”这个词,突然意识到。我在我的事件处理程序上使用了_.throttle,它破坏了preventDefault。这与原始问题无关,但无论如何谢谢!
      【解决方案9】:

      您可以使用以下代码禁用后退/前进:

      document.addEventListener("wheel", function(event) {
          event.preventDefault();
      }, { passive: false });
      

      请注意,添加 {passive: false } 是必不可少的,至少在 Chrome 中是这样。如果您只想在某些区域禁用后退/前进,则可以使用这样的代码(假设您使用的是 jquery,并将类 disable-back-forward 添加到要禁用后退/前进的部分):

      document.addEventListener("wheel", function(event) {
          if ($(event.target).closest('.disable-back-forward').length)
              event.preventDefault();
      }, { passive: false });
      

      【讨论】:

        【解决方案10】:

        您在错误的层面上看待问题。 OnBeforeUnload 根本没有被触发,因为从浏览器的角度来看没有任何东西被卸载。因此,坦率地说,您实现了错误的版本控制机制 - 片段用于页面状态,而不是您现在使用的文档状态。

        如果您坚持通过散列片段来维护状态,则需要使用另一种机制来防止页面状态更改。由于当前所有浏览器都支持 LocalStorage,我会使用它。好吧,在此过程中,将所有文档状态数据放在那里而不是在 URL 中,因为 Google Docs 就是这样做的,这就是他们没有这个问题的原因。

        【讨论】:

        • 我已经发现onbeforeunload 不起作用“我尝试过使用 window.onbeforeunload 但似乎不起作用”
        • 我认为您误解了这个问题。例如,如果用户在 div 中水平滚动,有时他们会到达末尾,然后 Chrome 会触发页面后退或页面前进动作。这与 url 哈希正交。 Google Docs 以某种方式禁用了此功能。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-12
        • 2019-12-04
        • 2017-03-20
        • 2013-07-02
        • 2020-06-30
        相关资源
        最近更新 更多