iPad / iPhone双击问题

时间:2011-09-27 17:19:04

标签: jquery iphone html ipad mobile

我遇到一个与iPad/iPhone hover problem causes the user to double click a link非常相似的问题,其中点按链接的用户必须点击两次以实际访问它。

我在那个问题中实现了解决方案,但我现在遇到了一个新问题。当用户点击链接时会发生重定向,但无论如何都会发生。因此,即使用户试图滚动页面,并且他们在链接上开始滚动,页面也会在他们放开滚动时重定向。

有没有办法保留链接,只需点击一下,但如果他们滚动,请不要重定向页面?

3 个答案:

答案 0 :(得分:7)

这是我最终做的事情:

问题在于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。
  4. 编辑:在此之后的一段时间,我发现问题是由SuperFish造成的。当页面在一定宽度下时禁用superfish解决了这个问题。

答案 1 :(得分:3)

我的建议是:

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

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

背景

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

  1. touchstart
  2. touchmove
  3. touchend
  4. 300毫秒延迟,浏览器确保这是一次点击,而不是双击
  5. mouseover
  6. mouseenter
    • 注意:如果mouseovermouseentermousemove事件更改了网页内容,则永远不会触发以下事件。
  7. mousemove
  8. mousedown
  9. mouseup
  10. click
  11. 似乎无法简单地告诉webbrowser跳过鼠标事件。

    更糟糕的是,如果鼠标悬停事件更改了网页内容,则点击事件永远不会被触发,如Safari Web Content Guide - Handling Events所述,特别是单指事件。究竟什么"内容改变"是,将取决于浏览器和版本。我发现对于iOS 7.0,背景颜色的变化不是(或不再是?)内容更改。

    解决方案

    回顾一下:

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

    请注意,touchend上没有任何操作!

    这显然适用于鼠标事件:mouseentermouseleavemouseovermouseout稍微改进的版本)会被触发,并添加和删除悬停。

    如果用户实际click是一个链接,则还会删除悬停效果。这可以确保在用户按下Web浏览器中的后退按钮时将其删除。

    这也适用于触摸事件:在touchstart上添加悬停效果。它不是'''''''''''已删除touchend。它会再次添加到mouseenter,因为这不会导致内容更改(已添加),所以click事件也会被触发,并且会跟踪链接,而无需用户再次单击!

    浏览器在touchstart事件和click之间的300毫秒延迟实际上得到了充分利用,因为悬停效果将在这么短的时间内显示。

    如果用户决定取消点击,则手指的移动将正常进行。通常,这是一个问题,因为没有触发mouseleave事件,并且悬停效果仍然存在。值得庆幸的是,通过删除touchmove上的悬停效果,可以轻松解决此问题。

    那就是它!

    请注意,可以删除300毫秒延迟,例如使用FastClick library,但这超出了此问题的范围。

    替代解决方案

    我发现以下问题存在以下问题:

    • 浏览器检测:极易出错。假设设备具有鼠标或触摸功能,而当触控显示器增加时,两者的组合将变得越来越常见。
    • CSS媒体检测:我唯一知道的仅限CSS的解决方案。仍然容易出错,并且仍假设设备有鼠标或触摸,但两者都是可能的。
    • 模拟touchend中的点击事件:这将错误地跟踪链接,即使用户只想滚动或缩放,而无意实际点击链接。
    • 使用变量来抑制鼠标事件:这会在touchend中设置一个变量,该变量在后续鼠标事件中用作if条件,以防止在该时间点发生状态更改。该变量在click事件中重置。如果您真的不想在触摸界面上悬停效果,这是一个不错的解决方案。不幸的是,如果touchend由于其他原因被触发并且没有触发点击事件(例如用户滚动或缩放),并且随后尝试使用鼠标跟踪链接(即在设备上鼠标和触摸界面)。

    进一步阅读

    另见Disable hover effects on mobile browsers

答案 2 :(得分:0)

如果您的内容位于UIScrollView,则可以(或可能已经)实施UIScrollViewDelegate;其中包含以下方法:

-(void)scrollViewDidScroll: (UIScrollView*)scrollView

如果您使用此功能,请获取以下内容:

float offset = scrollView.contentOffset.y;

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

如果您同时使用此条件并检测屏幕上当前点击/按下的次数(例如,只有一个情况),则忽略链接时可能发生的任何已触发的呼叫(如果> 1次点击)被轻拍。

希望这有帮助!