iPad/iPhone双击问题

4
我遇到了与iPad/iPhone hover problem causes the user to double click a link非常相似的问题,即用户点击链接需要点击两次才能打开链接。
我实施了那个问题中的解决方案,但现在出现了新问题。当用户点击链接时,重定向会发生,但不管什么情况都会发生重定向。因此,即使用户试图滚动页面,并且他们从链接开始滚动,当他们松开滚动时,页面也会重定向。
是否有一种方法可以保持链接只需要一个轻触,但如果他们正在滚动,则不会重定向页面?
3个回答

8

这是我的解决方法:

问题在于touchstart和touchend只识别触摸事件,而不是滚动事件,因此它们只对触摸的开始和结束做出反应。我们需要区分滚动和非滚动的情况。这是我所做的:

$('a')
    .live('touchstart', function(){
        isScrolling = false;
    })
    .live('touchmove', function(e){
        isScrolling = true;
    })
    .live('touchend', function(e){
        if( !isScrolling )
        {
            window.location = $(this).attr('href');
        }
    });

这些步骤按顺序进行:

  1. 当首次记录触摸时,将isScrolling设置为false。
  2. 当触摸移动时,将isScrolling设置为true。如果触摸没有移动,则不会发生此操作。
  3. 当触摸停止时,如果没有发生滚动,则将页面重定向到链接的href。

编辑:在此之后一段时间,我发现问题是由SuperFish引起的。在页面宽度达到一定值时禁用superfish解决了问题。


3

我的建议是:

  • touchstartmouseenter 上添加悬停效果。
  • mouseleavetouchmoveclick 上删除悬停效果。

这类似于Jake的回答,但无需模拟点击事件。

背景

为了模拟鼠标行为,像Webkit移动端这样的浏览器会在用户触摸并释放触摸屏幕(如iPad)上的手指时触发以下事件(来源:Touch And Mouse on html5rocks.com):

  1. touchstart(触摸开始)
  2. touchmove(触摸移动)
  3. touchend(触摸结束)
  4. 300毫秒的延迟,浏览器确保这是单击事件而不是双击事件。
  5. mouseover(鼠标悬停)
  6. mouseenter(鼠标进入)
    • 注意:如果mouseovermouseentermousemove事件改变了页面内容,则以下事件将不会被触发。
  7. mousemove(鼠标移动)
  8. mousedown(鼠标按下)
  9. mouseup(鼠标松开)
  10. click(鼠标单击)

似乎无法简单地告诉Web浏览器跳过鼠标事件。

更糟糕的是,如果鼠标悬停事件改变页面内容,则永远不会触发单击事件,正如Safari Web Content Guide - Handling Events中所解释的那样,特别是在One-Finger Events中的图6.4。什么是“内容更改”将取决于浏览器和版本。我发现,对于iOS 7.0,背景颜色的更改不是(或不再是)内容更改。
解决方案说明:
  • touchstartmouseenter上添加悬停效果。
  • mouseleavetouchmoveclick上删除悬停效果。
请注意,touchend上没有任何操作!
这显然适用于鼠标事件:mouseentermouseleave(稍微改进了mouseovermouseout的版本)被触发,并添加和删除悬停效果。
如果用户实际上点击了链接,悬停效果也会被移除。这确保了如果用户在Web浏览器中按下后退按钮,则其将被移除。
这也适用于触摸事件:在touchstart上添加悬停效果。它不会在touchend上被移除。它再次添加到mouseenter上,由于这不会引起内容更改(已经添加),因此还会触发click事件,无需用户再次点击即可跟随链接!
浏览器在touchstart事件和click之间具有300ms的延迟,实际上可以很好地利用这个时间,因为在这段短时间内将显示悬停效果。
如果用户决定取消单击,则手指移动就像正常情况一样。通常,这是一个问题,因为没有触发mouseleave事件,悬停效果仍然存在。幸运的是,这可以通过在touchmove上删除悬停效果来轻松解决。
就是这样!
请注意,可以通过使用FastClick库等方法来消除300毫秒的延迟,但这超出了本问题的范围。

替代方案

我发现以下替代方案存在以下问题:

  • 浏览器检测:极易出错。假设设备只有鼠标或触摸,而在触摸屏普及的情况下,两者结合使用将变得越来越常见。
  • CSS媒体检测:我所知道的唯一纯CSS解决方案。仍然容易出错,并且仍然假定设备只有鼠标或触摸,而两者都是可能的。
  • touchend中模拟点击事件:这将错误地跟随链接,即使用户只想滚动或缩放,而没有实际点击链接的意图。
  • 使用变量抑制鼠标事件:touchend中设置一个变量,该变量作为if条件用于后续鼠标事件,以防止此时状态发生变化。变量在单击事件中重置。如果您确实不希望在触摸界面上出现悬停效果,则这是一个不错的解决方案。不幸的是,如果由于其他原因触发了touchend并且没有触发单击事件(例如,用户滚动或缩放),则此方法无法工作,并且随后尝试使用鼠标跟随链接(即在具有鼠标和触摸界面的设备上)。

进一步阅读

另请参阅在移动浏览器上禁用悬停效果


0
如果你的内容在一个UIScrollView中,你可以(或者可能已经)实现了包含以下方法的UIScrollViewDelegate:
-(void)scrollViewDidScroll: (UIScrollView*)scrollView

如果您使用此功能,并获得以下结果:
float offset = scrollView.contentOffset.y;

if (offset > 0)
    // then we have started to scroll

如果您将此条件与检测当前屏幕上的敲击/按压数量结合使用(例如,在您的情况下仅为一次),那么请忽略任何在点击链接时可能发生的已触发呼叫(如果> 1 次敲击)。

希望这能对您有所帮助!


我想出了一个让它工作的方法。本来我想把它作为答案发布,但 Stack Overflow 不允许我在8小时内这样做。还剩55分钟。 - Jake

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