禁用 iOS 触摸屏设备的双击点击功能

5

最近,我正在改进和使网站响应式的工作中,其中一个问题是有许多元素可点击,使用了混合CSS和jQuery效果来实现悬停状态。

首先,我更喜欢所有这些悬停状态都由CSS控制,但我遇到的主要问题是,在这些悬停状态下,某些元素会改变displayvisibility CSS属性。我进行了一些阅读,显然如果是这种情况,在触摸屏iOS设备上,第一次“触摸”会强制启用悬停状态,然后需要第二次点击才能真正点击该元素。

我正在尝试寻找不需要大量标记和样式更改的解决方案。最好使用jQuery / JavaScript修复。

我已经尝试过以下方法:

$(document).ready(function() {
   $('a').on('click touchend', function(e) {
      var el = $(this);
      var link = el.attr('href');
      window.location = link;
   });
});

然而,当用户按住可点击元素并拖动页面进行滚动时,这会出现问题。当他们在拖动后松开手指时,window.location仍然被改变。
如果需要的话,我稍后会添加一个jsFiddle。
提前感谢您。
编辑:
这是一个显示问题的jsFiddle。 http://jsfiddle.net/0bj3uxap/4/ 如果您点击其中一个块,您将看到它显示悬停状态,然后您需要再次点击才能实际触发单击事件。
当元素被隐藏,然后悬停状态显示元素时,似乎会发生这种情况。
3个回答

3

看起来我找到了一个解决方案。

https://github.com/ftlabs/fastclick

FastClick可以解决这个问题,并消除某些移动浏览器的300毫秒延迟问题。

只需在<script>标签中引入库,然后使用jQuery或您喜欢的任何其他方法进行初始化:

$(document).ready(function() {
    FastClick.attach(document.body);
});

简单解释一下问题的原因:

当一个元素被隐藏时,例如它具有以下任何CSS属性之一:

display: none;
opacity: 0;
visibility: hidden;

隐藏元素的悬停状态将显示该元素,iOS在第一次触摸时不会触发点击事件,它会强制使用悬停状态(以显示元素)。然后用户需要再次触摸该元素才能触发点击事件。
我理解为什么要添加这个功能,但我认为我更希望iOS不要这样做,这样开发者只需调整他们的网站,不隐藏可能至关重要的内容。

非常感谢。它对我很有效。我的问题是:在iPad上,我必须点击两次标签<a>才能激活其链接。 - binhdocco
值得注意的是,如果在初始的touchstart/move/mousedown事件之后的约300毫秒内修改这些属性,iOS不会触发点击事件。因此,您仍然可以应用这些更改,但至少在初始加载时应等待更长时间。我下面提供了一个解决方案,使用cookie来暂时保存这个状态,以避免在后续页面加载时需要延迟。 - patricknelson

1
如果有人需要帮助:在我的情况下,我遇到了一个非常类似的问题,但它不仅仅是由于:hover样式。相反,原因是我使用了JavaScript事件监听器(touchstarttouchmovetouchend)来更改页面上元素的可见性(无论在哪里)。
在我的情况下,我只需向<html>标签添加一个touch类,以便检测设备是否支持触摸,并始终显示通常仅在悬停时显示的某些元素。我的解决方法有两个部分:
1.将延迟时间调整为> 300ms(即移动浏览器通常等待确定这是单击还是双击的时间)。在我的情况下,我只设置了500ms(请参见下面的第2条原因)。
2.然后,我使用cookie临时保留此设置,以便这些元素将立即可见,并且在随后的页面加载中不需要触摸事件监听器(因此,第一次延迟500ms不应成为交易破坏者)。
示例代码:
在这种情况下,使用jQuery + https://github.com/carhartl/jquery-cookie(修改以支持maxAge)。
function initTouchSupport() {
    // See if touch was already detected and, if so, immediately toggle the touch classes.
    if ($.cookie('touch-device')) {
        toggleTouch();
        return;
    }

    // Be efficient and listen once and, if ever detected, flag capability and stop listening (for efficiency).
    var events = 'touchstart touchmove touchend';
    $body.on(events, detectTouch);
    function detectTouch() {
        // Detected; retain for a short while (e.g. in case this is a laptop with touch capability and they switch
        // to mouse control). That way there's no delay on the next several page loads and no chance of a double-touch bug.
        $body.off(events, detectTouch);
        $.cookie('touch-device', true, {
            path: '/',
            domain: getDomain(),
            maxAge: 86400 // 86400 seconds = 1 day
        });

        setTimeout(toggleTouch, 500);
    }

    function toggleTouch() {
        // Swap out classes now
        $html.toggleClass('no-touch', false);
        $html.toggleClass('touch', true);
    }
}

0

我在IOS上遇到了一个非常类似的问题,需要双击按钮等等。我删除了所有包括一些悬停样式在内的桌面样式,但没有任何变化。我重新添加了那些在移动界面中并未使用的悬停样式。最后,问题出在一个名为

.error-message

的css类上。

更正一下,原来这个css类被用在我们的界面上,并且与鼠标悬停事件相关联。


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