Javascript 禁用双击以单击触摸屏iOS设备

Javascript 禁用双击以单击触摸屏iOS设备,javascript,jquery,ios,touchscreen,Javascript,Jquery,Ios,Touchscreen,所以,最近我一直在开发一个网站,该网站让我改进并做出响应,我面临的一个问题是,有许多元素是可点击的,它们混合了CSS和jQuery的悬停状态效果 现在,首先,我希望所有这些悬停状态都是CSS,但我面临的主要问题是,在这些悬停状态上,某些元素正在更改display和visibilityCSS属性。我读了一些资料,显然如果是这样的话,在触摸屏iOS设备上,这会导致第一次“触摸”强制进入悬停状态,然后需要第二次点击才能真正点击元素 我试图找到一个不需要大量标记和样式更改的解决方案。最好是利用jQuer

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

现在,首先,我希望所有这些悬停状态都是CSS,但我面临的主要问题是,在这些悬停状态上,某些元素正在更改
display
visibility
CSS属性。我读了一些资料,显然如果是这样的话,在触摸屏iOS设备上,这会导致第一次“触摸”强制进入悬停状态,然后需要第二次点击才能真正点击元素

我试图找到一个不需要大量标记和样式更改的解决方案。最好是利用jQuery/JavaScript进行修复

我尝试了以下方法:

$(document).ready(function() {
   $('a').on('click touchend', function(e) {
      var el = $(this);
      var link = el.attr('href');
      window.location = link;
   });
});
display: none;
opacity: 0;
visibility: hidden;
但是,当用户将手指放在可单击的元素上并拖动页面滚动时,会出现问题。当他们在拖动后松开手指时,
窗口位置仍会更改

如果必要的话,我稍后会添加一个JSFIDLE

提前谢谢

编辑:

这里有一个JSFIDLE显示了这个问题。 如果您点击其中一个块,您将看到它显示悬停状态,然后需要再次点击以实际触发click事件


当一个元素被隐藏,然后悬停状态显示该元素时,似乎会发生这种情况。

看起来我找到了解决方案

FastClick修复了此问题,并消除了某些移动浏览器的300毫秒延迟问题

只需将库包含在
标记中,然后使用jQuery或任何您喜欢的方式启动它:

$(document).ready(function() {
    FastClick.attach(document.body);
});
简单解释一下问题发生的原因:

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

$(document).ready(function() {
   $('a').on('click touchend', function(e) {
      var el = $(this);
      var link = el.attr('href');
      window.location = link;
   });
});
display: none;
opacity: 0;
visibility: hidden;
然后隐藏元素的悬停状态显示该元素,iOS不会在第一次触摸时触发click事件,而是强制悬停状态(显示该元素)。然后,用户需要再次触摸该元素以触发单击事件


我明白为什么添加了这个,但我想我宁愿iOS不这样做,然后开发者只需要定制他们的网站,以避免隐藏可能至关重要的内容。

我在iOS中遇到了一个非常类似的问题,必须使用双选项卡按钮等,我删除了所有桌面样式,其中包括一些悬停样式。这没有什么区别。我将鼠标悬停样式放回移动UI中未使用的位置。最后,问题是一个名为

.错误消息


更正事实证明,这个css已经在我们的UI中使用过,并且它被链接到一个鼠标悬停事件,如果它对其他人有帮助的话:在我的例子中,我有一个非常类似的问题,但是这不仅仅是因为它本身的
:hover
风格。相反,这是因为我使用JavaScript事件监听器(
touchstart
touchmove
touchend
)来更改页面上元素的可见性(无论在何处)

在我的例子中,我只是简单地在
标签中添加了一个
touch
类,以便检测设备是否能够触摸,并且应该始终显示某些通常仅在悬停时显示的元素。我的解决方案有两个方面:

  • 移动到>300ms延迟(即移动浏览器在确定这是单次点击还是双击之前通常可能等待的时间)。在我的例子中,我选择了500毫秒(原因见下文第2节)
  • 然后,我使用cookie临时保留此设置,以便这些元素立即可见,并且在随后的页面加载中不需要触摸事件侦听器(因此,第一次延迟500毫秒不应成为交易的破坏者)
  • 示例代码:

    在本例中,使用jQuery+(修改为支持
    maxAge

    函数initTouchSupport(){
    //查看是否已检测到触摸,如果已检测到,请立即切换触摸类别。
    如果($.cookie('touch-device')){
    toggleTouch();
    返回;
    }
    //高效地听一次,如果检测到,则标记功能并停止听(以提高效率)。
    var事件='touchstart touchmove touchend';
    $body.on(事件,检测点);
    函数detectTouch(){
    //检测到;保留一段时间(例如,如果这是一台具有触摸功能的笔记本电脑,它们会切换
    //这样就不会延迟接下来的几次页面加载,也不会出现双击错误。
    $body.off(事件,检测点);
    $.cookie('touch-device',true{
    路径:“/”,
    域:getDomain(),
    最大值:86400//86400秒=1天
    });
    设置超时(toggleTouch,500);
    }
    函数toggleTouch(){
    //现在交换课程
    $html.toggleClass('no-touch',false);
    $html.toggleClass('touch',true);
    }
    }
    
    非常感谢。它对我很有效。我的问题是:我必须在标签上点击两次才能激活iPad上的its链接。另外值得注意的是,如果在初次touchstart/move/mousedown的300毫秒内修改这些属性,iOS不会触发点击事件。所以,您仍然可以应用这些更改,但至少在初始加载时,您应该再等一会儿。我在下面有一个解决方案,它使用cookies临时保存此内容,以防止后续页面加载需要延迟。