跨度在锚标记内阻止 iPhone 上 Safari 的点击事件

Posted

技术标签:

【中文标题】跨度在锚标记内阻止 iPhone 上 Safari 的点击事件【英文标题】:Span inside anchor tag blocks tap event for Safari on iPhone 【发布时间】:2012-05-28 07:11:25 【问题描述】:

我在基于 Sencha Touch 2 的移动应用程序中将普通链接设置为类似于按钮的样式,但我遇到了大部分链接在 iPhone 上的 Safari 中不起作用的问题。

链接是一个普通的<a> 标记,内部有一个包含标签文本的<span> 元素。 <a> 元素上有填充,允许注册点击。似乎内部<span> 阻止了tap 在父锚中注册为链接tap,并且它的背景是透明的。

这是标记:

<a href="http://test-site.xx/full-site-page?param=value" class="x-button-normal x-button btn-profile">
    <span class="x-button-label">View profile on full site</span>
</a>

在 Chrome 中对此进行测试不会出现任何问题,即单击 span 会导致跟随父超链接。两者都是基于 Webkit 的浏览器。我们的一位测试人员还在 Macbook 上的 Safari 中进行了测试,没有出现任何问题;我还使用 Wacom Bamboo 平板电脑在 Chrome 中对此进行了测试,没有任何问题。这只是移动设备上的一个问题(在 iPhone 和 android 2.2 上测试过)——这是我们的目标。

我可以在&lt;span&gt; 元素上设置一个 CSS 属性以允许点击进入父超链接吗?理想情况下,我想避免通过 javascript 设置事件。关于为什么这不能像我预期的那样工作的任何想法?

更新:以下是 Chrome 开发者控制台报告的内部跨度样式:

-webkit-box-align: center;
-webkit-box-flex: 1;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-user-drag: none;
-webkit-user-select: none;
background-attachment: scroll;
background-clip: border-box;
background-color: transparent;
background-image: none;
background-origin: padding-box;
border-bottom-color: white;
border-bottom-style: none;
border-bottom-width: 0px;
border-left-color: white;
border-left-style: none;
border-left-width: 0px;
border-right-color: white;
border-right-style: none;
border-right-width: 0px;
border-top-color: white;
border-top-style: none;
border-top-width: 0px;
box-shadow: none;
box-sizing: border-box;
color: white;
cursor: auto;
display: inline;
font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans', sans-serif;
font-size: 18px;
font-weight: bold;
height: auto;
line-height: 21px;
overflow-x: hidden;
overflow-y: hidden;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
position: static;
text-align: center;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
width: auto;    

非常感谢。

【问题讨论】:

为什么在'a'标签内需要span标签? span 是否以任何方式设置样式(它有一个类,所以我假设是的)?它是否被设置为 display: block 而锚仍然内联或类似的东西?也许发布你的CSS。另外,您能否在同时具有触摸屏指针设备和/或键盘的设备上进行测试?指针或键盘可以激活链接吗?这些可以缩小可能的原因。 感谢您的想法。锚标记和内部跨度的display 设置为block;即使在重构之后将 span 元素设置为display: inline;,按钮标签(即内部跨度)仍然不允许点击进入超链接。跨度之外的区域仍然作为超链接工作,因此&lt;a&gt; 是一个块不太可能会影响这一点。 @Sowmya,内部跨度用于按钮标签文本,以便我们可以重用 SenchaTouch 框架为按钮设置的 CSS 样式。我们的移动网站设计要求它看起来像一个常规按钮,即使它实际上是一个超链接。 Sencha 按钮是具有内部跨度的 &lt;div&gt; 元素。我们还提供具有多个元素(文件图标、名称和文件大小文本)的下载链接,每个元素都有自己的样式要求。这些是根据数据动态生成的,也受此问题的影响。 【参考方案1】:

解决了,感谢this post,它提到了以下 CSS 属性:

pointer-events: none;

将此添加到内部&lt;span&gt; 的样式(以及在我的第二条评论中提到的内部浮动&lt;img&gt;)允许这些通过点击传递到父超链接。

奇怪的是 Sencha Touch 2 似乎干扰了 DOM,不知道具体是什么。在完全静态的 html 页面(没有 JavaScript,更不用说 Sencha Touch 2)上模拟一个类似样式的按钮并没有在移动设备上表现出最初的问题。

在简单的情况下(单个&lt;span&gt;,没有浮动图像)的另一个选择是重构样式以消除对内部&lt;span&gt; 的需要,尽管这对于更复杂的情况是不可行的:

<a class="attachment" href="/someRepository/someDownload.pdf">
    <img src="/images/fileExtension-pdf.png" />
    <span class="title">Title of download</span>
    <span class="size">xxx kB</span>
</a>

【讨论】:

也适用于&lt;span&gt; 内的&lt;label&gt; 也适用于 &lt;span&gt; 内的 &lt;div&gt;,在 div 上有点击事件。【参考方案2】:

我认为这与 Sencha Touch 防止缩放有关。他们在代码中添加了防止默认的大多数 touchstart 事件(这会破坏链接的使用)。锚点有一个例外,但锚点的子节点没有(因此点击锚点本身可以​​正常工作,但不能点击锚点内的跨度)。我能够在我的应用程序启动方法中对 quickfix 进行猴子补丁:

Ext.Viewport.setPreventZooming(false); // unbind any existing handler
Ext.Viewport.doPreventZooming = Ext.Function.createInterceptor(Ext.Viewport.doPreventZooming, function(e)
    return !Ext.fly(e.target).findParent('a');
    );
Ext.Viewport.setPreventZooming(true);

上面的代码没有任何保证(没有在 Android 上测试过,我怀疑它效率很低)。我也将此报告为错误:http://www.sencha.com/forum/showthread.php?215032-Links-are-prevented-when-tapping-on-children

【讨论】:

以上是关于跨度在锚标记内阻止 iPhone 上 Safari 的点击事件的主要内容,如果未能解决你的问题,请参考以下文章

一段时间内阻止多次登录不成功的请求

发送短信后60秒内阻止点击 + 手机号码检测

如何在锚文本后添加跨度?

将字体真棒跨度图标放置在锚点内的文本上方

css:在锚标记上添加背景图像 URL

在使用 CSS 自定义属性设置的 Chrome 背景图像上,在锚标记内时会闪烁