【问题标题】:Mobile Safari sometimes does not trigger the click eventMobile Safari 有时不会触发点击事件
【发布时间】:2014-06-06 08:47:53
【问题描述】:

这是我正在开发的动态 JavaScript 应用程序。我有很多 <a> 有一个类的锚元素。单击该类时,应该会发生一些事情。这在 Firefox、Chrome、IE 中运行良好,但在某些情况下在移动 Safari(iPad 和 iPhone)上不会触发点击事件。

这些元素都有完全相同的 CSS,只是它们的位置不同(它们在不同的容器中)。

我尝试了在这里找到的各种解决方案,但都没有成功。例如:

您还有其他想法可以帮助我找到解决方案吗?为什么点击事件只在某些情况下触发?

【问题讨论】:

  • 你应该有一个 href 属性来确保锚点正常工作。在 js 中使用 .preventDefault() 来对抗它的行为。
  • 谢谢凯尔。添加了hrefs但没有运气。其他有效的元素也没有href。我应该如何使用 .preventDefault()?
  • 应用使用了jQuery,所以在其点击函数中有.preventDefault()。

标签: javascript jquery css mobile-safari dom-events


【解决方案1】:

在 iOS 上点击所产生的点击事件会在某些条件下按预期冒泡——您提到的其中之一是光标样式。这是另一个:

目标元素,或它的任何祖先,但不包括 <body>,为任何鼠标设置了显式事件处理程序 事件。此事件处理程序可能是一个空函数。

http://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html

这是更好的修复向量,无需浏览器检查即可完成。由于“不包括<body>”部分,您必须添加一个额外的div:

<body>
  <div onclick="void(0);">
    <!-- ... all your normal body content ... -->
  </div>
</body>

现在,源自该 div 的每个点击事件都会在 iOS 中按预期冒泡(这意味着您可以使用 $(document).on('click', '.class', etc...) 捕获它们)。

【讨论】:

  • 我会选择body { cursor:pointer; }。很多代码向body插入动态元素,我不想全部修改。
  • @deerchao 它不会对其他浏览器产生副作用吗?因为这个简单的 CSS 语句有效! :)
  • 3 年后,这仍然是移动版 Safari 的解决方案。一切都在 Chrome 和 Firefox 上运行,但 Safari 我们必须将其添加到只有少数无法正确触发的父容器中,更喜欢隔离方法。
  • 我在 React with material-ui 中遇到了这个错误,并添加了一个虚拟 onClick={function(){}} 允许在我的元素上正确调用 mouseleave 事件。这很疯狂,但它奏效了。
【解决方案2】:

你试过吗?这是因为ios有时不会触发点击事件,只识别触摸事件

$(document).on('touchstart click', [Selector], [ Event ]

【讨论】:

  • 谢谢。似乎添加 touchstart 事件有效。但是,这可能不是最佳解决方案,因为即使用户只是尝试滚动并开始将手指放在该链接上,也会触发操作。有没有比使用touchstart 更好的方法?
  • 对我来说,这最终触发了两次,并且我有一个切换我的弹出窗口显示一瞬间然后再次隐藏。
【解决方案3】:

只需声明这些空事件侦听器就可以了。试试看吧:)

这将使它适用于所有浏览器:

container.addEventListener('touchstart', () => {});
container.addEventListener('touchend', () => {});
container.addEventListener('touchcancel', () => {});
container.addEventListener('touchmove', () => {});

【讨论】:

  • 有趣。你能详细说明为什么这样有效吗?因为它运作良好!
【解决方案4】:

还有一个针对移动设备的附加事件。除了click 事件之外,尝试添加tap 事件侦听器。它们可以与以下内容同时附加:

$(document).on('click tap', [selector], [handler])

【讨论】:

  • 谢谢,我猜你的意思是tap。我尝试了大多数没有结果的事件。
  • 也许发布结构会有所帮助,这样人们就可以看到 DOM。也许事件是在其他地方捕获的,而不是冒泡
【解决方案5】:

对我来说,这种行为是随机的。一切正常,但经过一些更改后,触发某些按钮的点击事件时确实出现了随机问题。

问题是一些移动设备的按钮悬停(对我来说至少有一些带有 Safari 的 iOS iPad) 我通过在所有悬停中添加@media 悬停和指针添加来修复它:

@media (hover: hover) and (pointer: fine) {
    .topnav a:hover {
        background-color: lightcoral;
    }
}

这篇文章帮助我解决了这个问题(即使我在这里不使用 react)https://github.com/facebook/react/issues/7635#issuecomment-365089006

【讨论】:

    【解决方案6】:

    这是一个疯狂的问题,确实LinusR's answerdescription on quirksmode 是准确的。由于这个原因,我的一般点击事件监听器在 iOS Safari 中不起作用:

    window.addEventListener('click', function(event) {
        alert("Where's my click?!");
    });
    

    我现在已经用 &lt;div onclick="void(0);"&gt;&lt;/div&gt; 包装了我的应用程序,这很有效。我还添加了一些额外的东西来解决由此产生的一些问题:

    <div onclick="void(0);" style="height: 100%; -webkit-tap-highlight-color: transparent;">
      <div style="height: 100%; -webkit-tap-highlight-color: initial;">
        <my-app></my-app>
      </div>
    </div>
    

    我需要height: 100%; 才能在整个页面上提供点击,因为我需要它。如果你不这样做height: 100%;,点击事件仍然只会在 div 的高度内触发。

    -webkit-tap-highlight-color: transparent; 用于防止 onclick flash 覆盖样式,因为 iOS 默认使用可点击元素来执行此操作。之后的 div 恢复了该 CSS 属性的初始值,因此其他可点击元素在这方面确实具有正常行为。请参阅this answer 了解更多信息。

    【讨论】:

      【解决方案7】:

      刚刚花了一个小时调试另一个疯狂的场景,Safari 吞下水龙头,因为上述提示都没有帮助,而且问题似乎突然出现。

      tl;dr:如果底层 CSS 导致悬停时重排,则冒泡不会到达发生重排的元素。

      考虑以下标记:

      container
        div 
          span
      
          container.addEventListener('click', MouseClick, false)
      
      span {opacity: 0;} 
      
      div:hover {
          span {opacity: 1;}
       }
      

      因此,在移动 Safari 中点击时,div 元素不会收到 click 事件,因为第一次点击等于悬停事件,这会触发 span 上的 CSS 重排(它比 div 小得多,并且在点击目标坐标之外)。同时,在同一个 div 中还有其他 css hover 事件发生,不会导致点击丢失。

      当我把它缩小到这个 CSS 时,我大吃一惊。幸运的是它昨天被添加到代码库中并且很容易追踪,但是神圣的网络,Safari 真的很糟糕。

      【讨论】:

        【解决方案8】:

        在我的例子中,按钮有一个:hover/:focus,它的大小可以改变属性,比如边框:3px。

        微小的尺寸变化足以重排位置并使点击无效。

        它发生在移动设备上只是因为空间有限。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-10
          • 2018-04-18
          • 2020-05-21
          • 2020-12-27
          • 1970-01-01
          • 2023-03-13
          • 1970-01-01
          相关资源
          最近更新 更多