禁用双击点击触摸屏 iOS 设备

Disable Double Tap To Click On Touchscreen iOS Devices

所以,最近我一直在开发一个网站,让我改进并做出响应,我遇到的问题之一是有许多可点击的元素, CSS 和 jQuery 悬停状态效果的混合。

现在,首先我希望所有这些悬停状态都是 CSS,但我遇到的主要问题是在这些悬停状态下,某些元素正在改变 display 并且visibility css 个属性。我做了一些阅读,显然如果是这种情况,在触摸屏 iOS 设备上,这会导致第一个 'touch' 强制悬停状态,然后需要第二次单击才能实际单击该元素。

我正在尝试寻找不需要大量标记和样式更改的解决方案。最好是修复利用 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/ 如果您点击其中一个方块,您会看到它显示悬停状态,然后您需要再次点击才能真正触发点击事件。

好像是隐藏了一个元素,然后悬停状态显示了这个元素。

看来我找到了解决办法。

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 不这样做,然后开发人员只需要定制他们的网站,不要隐藏可能很重要的内容。

我在 IOS 中遇到了一个非常相似的问题,必须双标签按钮等我删除了所有桌面样式,其中包括一些悬停样式,这没有任何区别。我将移动设备中未使用的悬停样式放回 UI。最后,问题是 css class 称为

.错误信息

更正原来这个 css 已在我们的 UI 中使用并且它链接到鼠标悬停事件

如果对其他人有帮助: 在我的例子中,我遇到了一个非常相似的问题,但这不仅仅是因为它自己的 :hover 风格。相反,这是因为我使用 JavaScript 事件侦听器(touchstarttouchmovetouchend)来更改页面上元素的可见性(无论在何处).

在我的例子中,我只是将 touch class 添加到 <html> 标签,以检测设备是否能够触摸并且应该始终显示某些元素通常只在悬停时显示。我的修复是双重的:

  1. 移动到 >300 毫秒的延迟(即移动浏览器在确定这是单击还是双击之前通常可能等待的时间)。就我而言,我刚定下 500 毫秒(请参阅下面的 #2 了解原因)。
  2. 然后我使用 cookie 暂时保留此设置,以便这些元素立即可见,并且在后续页面加载时不需要触摸事件侦听器(因此第一次延迟 500 毫秒不应该是交易破坏者)。

示例代码:

在这种情况下,使用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);
    }
}