14

上下文:MobileSafari/iPad 上的 Web 应用程序,全屏和嵌入 iframe

目标:为PressTap不是 Pinch(缩放)或Drag(滚动/平移)提供自定义事件处理程序的技术。我们希望为 Press 提供自定义行为,但仍然让 Safari 处理 Scroll/Pan/Zoom。

问题:这两个目标似乎是相互排斥的。为了防止 Press 手势的默认行为,必须立即调用event.preventDefault以响应ontouchstart。但是,要让默认行为在 Drag 上继续进行,我们不能在初始 ontouchstart 上调用 event.preventDefault。一旦调用了 preventDefault,就无法在该手势序列期间恢复默认行为(即直到所有手指都松开)。在发生某些移动之前,无法识别拖动。

拖动是最简单的示例,但我们也关心获得捏合和双击的默认行为。我们从不想要“复制图像”或选择文本的默认 MobileSafari Press 行为。

迄今为止的尝试:

  • 保存 ontouchstart 事件,并在timeout之后调用 preventDefault (就在 Press 被识别之前)。没有效果。
  • 听“ oncontextmenu ”。不,默认的 Press 行为不会通过此事件发出信号或路由。
  • 在我们所有的 ontouch* 处理程序中阻止默认设置,然后当我们识别到拖动/捏合手势时,使用initTouchEvent和/或initGestureEvent模拟新事件。以编程方式创建的事件会触发我们所有的回调,但 Safari 似乎没有注意到它们,不会触发任何默认行为。
  • 用一个假动作破坏 Safari 的 Press 识别。Safari 会在最轻微的移动时取消按下,但我们允许有一点马虎。如果手指没有“真正”移动,则在 ontouchstart 之后模拟移动事件(如上)不会导致 Safari 无法识别 Press。

我们以 Apple原生 iOS 手势识别器的风格实现了一套功能齐全的手势识别器(在 Javascript,ontouch* 中)。我们识别任何手势都没有问题,我们只是不知道复制 Safari 免费提供的缩放/平移/双击行为的好方法。

我们不需要代码;我们正在寻找任何理论上的解决方案(除了“自己也可以实现平移/缩放”,但如果您有一种我们感兴趣的巧妙方法),可以带来合理的成功。我们也有兴趣了解其他类似的尝试——当然我们不可能是第一个尝试这个的人吗?

备用 TL;DR:除了在 touchstart 中,还有什么方法可以防止默认的 Press(也称为点击并按住)?

4

2 回答 2

19

成功:完全通过 CSS 而不是 preventDefault 来阻止“默认按下”行为。这个答案是由 Safari Technologies 布道者Vicki Murley这里提供的(需要注册)

我在您的 stackoverflow 帖子中看到您说您的最终目标是:

“我们从不想要“复制图像”或选择文本的默认 MobileSafari Press 行为。”

这些行为可以在 CSS 中禁用(+ 一个额外的属性,因为人们在关闭这些其他行为时通常希望关闭突出显示):

/* behavior */
-webkit-user-select: none;                /* disable cut copy paste */
-webkit-touch-callout: none;              /* disable callout, image save panel */
-webkit-tap-highlight-color: transparent; /* "turn off" link highlight */

评论:我们假设 Safari 的 Press 行为是基于事件的,而不是由 CSS 驱动的。调用 preventDefault ontouchstart 确实会取消按下行为(这确实是导致我们误入歧途的原因),但这似乎是一个意外的副作用。实际上,Mobile Safari 不像“CSS on press”那样执行“按下事件”。

使用 CSS 禁用 Press 行为使我们能够再次调用 preventDefault 仅在我们真正需要的地方和时间。

于 2011-03-30T21:38:24.457 回答
0

丑陋的可能性:不要阻止新闻 - 让默认新闻什么也不做。尝试使用可以捕获所有触摸并且不会阻止 touchstart 上的任何内容的玻璃窗格 div。

Div 确实具有默认的 Press 行为(某种选择),但也许可以关闭它,不是通过 preventDevault 而是通过<body style="-webkit-user-select:none">? 参考

这意味着我们必须进行自己的命中测试以确定将我们识别的事件传递给哪些 DOM 节点,因为我们不能让事件在 DOM 祖先链中冒泡。

于 2011-03-30T20:24:25.680 回答