在iPad Safari中防止网页之间的滑动切换

16

在我的iPad Safari浏览器中,从左右边缘向右或向左滑动会切换当前打开的网页。有没有办法防止这种情况发生?

我尝试在页面边缘添加touchstarttouchmove处理程序,并使用stopPropagationpreventDefault来阻止它们,但似乎没有效果,touch-actionCSS也是如此。

类似的问题在2014年被问及,回复是否定的: iOS 7 - is there a way to disable the swipe back and forward functionality in Safari?

现在在2018年是否有解决方法?


4
我不建议这么做。在浏览器中禁用必要的导航操作会让用户感到困惑。 - Tamás Sengel
6
我的应用是一个单页应用程序,允许用户在屏幕上移动卡片。让用户感到困惑的是,如果他们开始尝试移动靠近屏幕边缘的卡片,整个页面会一起移动。Android Chrome解决了这个问题,只允许在Chrome栏上进行导航滑动操作。 - ᴇʟᴇvᴀтᴇ
1
解决方案将为屏幕中央提供所谓的安全区域,卡片可以在此自由移动。 - Tamás Sengel
2
这是一种解决方案,但对用户来说不太直观/舒适。我还有一个分屏模式,其中可以拖动分隔符并将其停靠在屏幕的任一侧。这在任何地方都有效,但在iOS Safari中则不行。一旦停靠,它就无法移动,因为屏幕边缘周围的触摸事件丢失,任何尝试移动它的操作结果都会变成在网页之间滑动。 - ᴇʟᴇvᴀтᴇ
6个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
11
在 iOS 13.4+ 中,你现在可以在 "touchstart" 上使用 preventDefault。假设我们在页面上有一个
,它跨越视口的整个宽度,我们希望阻止在该元素上进行滑动导航。
const element = document.querySelector('.block-swipe-nav');

element.addEventListener('touchstart', (e) => {

    // is not near edge of view, exit
    if (e.pageX > 10 && e.pageX < window.innerWidth - 10) return;

    // prevent swipe to navigate gesture
    e.preventDefault();
});

我写了一篇关于如何阻止滑动操作的短文,还附带了一些额外的信息。


1
在iOS 14中,如果浏览器处于全屏模式,则此操作将不再阻止在Safari中的任何位置进行触摸和下拉事件。它将始终将浏览器拖出全屏模式。 - Johncl

3

在iOS9之后,苹果提供了以下准则。

该指南允许您禁用

  1. Scrolling

    function touchMove(event) {
      // Prevent scrolling on this element
      event.preventDefault();
      ...
    }
    
  2. Pinch and Zoom

    function gestureChange(event) {
      // Disable browser zoom
      event.preventDefault();
      ...
    }
    
你可以按照以下方式识别滑动手势:
  1. 如果您收到一个包含一个目标触摸的touchstart事件,则开始手势。
  2. 如果在任何时候收到一个包含>1个触摸的事件,则中止手势。
  3. 如果您接收到大多数是x方向的touchmove事件,则继续手势。
  4. 如果您接收到大多数是y方向的touchmove事件,则中止手势。
  5. 如果您收到touchend事件,则结束手势。
完整指南发布在这里。 如果需要更多帮助,请告诉我。 Nitin, Defuzed

3
我已经知道如何从触摸事件中解释滑动手势。问题在于在屏幕边缘浏览器的行为是不同的。它会在不同页面间切换,而我找不到任何方法来阻止这种行为。 - ᴇʟᴇvᴀтᴇ
4
@ᴇʟᴇvᴀтᴇ ... 你可能找不到一种方法,而不是使用非常hacky的方式。看起来像是本地浏览器功能,作为Web开发人员,你无法控制...这就是这个特定浏览器的工作原理。你所能做的最好的办法就是向用户提供行为警告信息。我认为你的手脚被束缚了。 - zgood
6
嗯,是的,看起来似乎没有办法阻止它。我想知道苹果是否有意为之,让网络应用难以与App Store本地应用竞争。 - ᴇʟᴇvᴀтᴇ

3

无法实现,自iOS早期以来就一直存在这个问题。他们在强大的Web应用程序功能(例如服务工作者和WebGL)方面一再拖延。

对于每个浏览器,您所能做的最好的事情是使用功能检测,尽可能地提供最佳体验。已经过去了让所有网站在每个浏览器上看起来都相同的时代。

如果需要,可以使用三明治式布局,在支持侧滑的浏览器上允许侧滑操作。禁用少数浏览器中的某些小功能,以造福更多用户,这没有任何羞耻之处。


针对游戏、图表或任何用户应该能够在屏幕的任何位置进行高级交互的情况,这种方法并不可行。主要问题是,苹果公司及其同行将其浏览器视为仅用于查看网页和查看图片的简单页面浏览器,而不是其他任何活动。 - Kev

1

看起来没有办法禁用这个功能,所以我找到了一个解决方法,就是在页面的左右两侧设置24像素的死区,可以防止意外导航。

这是我的CSS代码:

body {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 24px;
  right: 24px;
  background-color: #ccc;
}
使页面主体元素的 position: fixed 属性可以避免 Safari 浏览器出现令人讨厌的过度滚动/弹跳效果。

1
有趣的黑客攻击! - parreirat
这在iOS 13上不起作用。仍然可以从屏幕左侧滑动以触发后退导航。 - Felix Turner
是的,似乎没有办法阻止导航。这个解决方法的重点是让用户更清楚地知道页面旁边的区域不是 Web 应用程序的一部分。 - ᴇʟᴇvᴀтᴇ

0

如果有导航历史记录,就可以通过滑动手势进行导航。向左滑动是“返回到我的导航历史记录中的上一页”。

因此,如果您的应用程序不需要导航历史记录(例如单屏游戏),则您可以通过删除导航历史记录来防止滑动问题

例如,我有一个只使用内存历史记录的单页面应用程序,我不与浏览器同步(历史记录/ URL)。因此,“滑动”无处可去,从而“修复”了这个问题。

话虽如此,这是一种解决方法,它有其局限性,可能对您的情况不够好。(在互联网上共享URL是基本的事情)

看起来,浏览器供应商的使命是通过诸如此类的愚蠢事情使Web开发人员的生活变得痛苦。


这听起来很有趣,但我不完全明白如何实现它。你能解释一下如何“删除导航历史”吗?在我的iPad上,滑动手势是在打开的标签之间切换(这些标签不在我的控制范围内)。 - ᴇʟᴇvᴀтᴇ
在我说任何话之前,你的应用程序在线可以查看吗? - Kev
不,我从未将其推向世界。(或者,至少还没有) - ᴇʟᴇvᴀтᴇ
2
我看到了你在2018年的问题..,参考别人在2014年的问题。好吧,现在已经快到2020年了,但这仍然是个问题。没有你应用程序情况的详细信息,我只能讲讲我们的情况。我们在iphone 5S / ipad上测试了ios 12和13。我们的SPA是一个react应用程序,并且我已经删除与浏览器历史记录同步的导航。我制作了自己的路由器,所以我不会在这里解释它。但如果你想要一个例子,那就相当于使用React Router“Memory Router”。https://reacttraining.com/react-router/web/api/MemoryRouter - Kev
1
很遗憾,您无法清除浏览器历史记录。您可以在不添加到历史记录的情况下浏览您的应用程序,但如果用户通过其他网站访问您的网站,则始终会存在历史记录。一种选择是,如果历史对象在进入您的应用程序时过长,则在弹出窗口中打开您的应用程序。 - pieroxy
显示剩余2条评论

-1
<body> 标签中尝试这个:
onload='ontouchmove()="return(function(event) { event.preventDefault(); event.stopPropagation(); return(false); } );"'

我想如果不告诉IOS关于移动的话可能会有一些副作用,但对于SPW来说可能只是轻微的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,