【问题标题】:Click event called twice on touchend in iPad在 iPad 的 touchend 上调用两次点击事件
【发布时间】:2011-12-14 11:05:53
【问题描述】:

我正在为幻灯片使用 jquery animate。我在幻灯片的末尾有一个箭头,并在该箭头上给出了点击事件。它的工作原理是在单击时在 silde 内移动一个项目,并在 mousedown 时移动整个 silde。这在桌面上运行良好,但在 iPad 中,点击时幻灯片中一次有两个项目。我不明白为什么在 iPad 中点击事件会被调用两次。点击的示例代码是:

    $('#next_item').bind('mousedown touchstart MozTouchDown',function(e) {                    
        $('.slide').animate({left:left},6000);   
    });

    $('#next_item').bind('mouseup touchend MozTouchRelease',function(e) {   
        No.nextItem();          
    });

#next_item 是幻灯片末尾箭头的 ID。我曾尝试 unbind touchstarttouchend 事件,但在滑动滚动期间,由于取消绑定,该项目不会在单个项目后进入幻灯片内。 No.nextItem() 在幻灯片内移动一项。 left in $('.slide') 是向左移动幻灯片。请帮我找出为什么会发生这种情况的解决方案以及如何为 ipad 解决这个问题。

【问题讨论】:

    标签: jquery ipad click touch


    【解决方案1】:

    iPad 都支持 touchstart/-end 和 mousestart/-end。

    是这样被解雇的:

    ┌─────────────────────┬──────────────────────┬─────────────────────────┐
    │Finger enters tablet │ Finger leaves tablet │ Small delay after leave │
    ├─────────────────────┼──────────────────────┼─────────────────────────┤
    │touchstart           │ touchend             │ mousedown               │
    │                     │                      │ mouseup                 │
    └─────────────────────┴──────────────────────┴─────────────────────────┘
    

    您必须检测用户是否在平板电脑上,然后在触摸启动的事情上进行中继...:

    /********************************************************************************
    * 
    * Dont sniff UA for device. Use feature checks instead: ('touchstart' in document) 
    *   The problem with this is that computers, with touch screen, will only trigger 
    *   the touch-event, when the screen is clicked. Not when the mouse is clicked.
    * 
    ********************************************************************************/
    var isIOS = ((/iphone|ipad/gi).test(navigator.appVersion));
    var myDown = isIOS ? "touchstart" : "mousedown";
    var myUp = isIOS ? "touchend" : "mouseup";
    

    然后像这样绑定它:

    $('#next_item').bind(myDown, function(e) { 
    

    您还可以创建一个事件来处理它,请参阅:

    http://benalman.com/news/2010/03/jquery-special-events/

    基本归一化向下事件:

    $.event.special.myDown = {
        setup: function() {
            var isIOS = ((/iphone|ipad/gi).test(navigator.appVersion));
            var myDown = isIOS ? "touchstart" : "mousedown";
            $(this).bind(myDown + ".myDownEvent", function(event) {
                event.type = "myDown";
                $.event.handle.call(this, event);
            });
        },
        teardown: function() {
            $(this).unbind(".myDownEvent");
        }
    };
    

    在 jQuery 1.9.0 之后 $.event.handle 更名为 $.event.dispatch,为了支持两者,你可以编写使用这个后备:

    // http://stackoverflow.com/questions/15653917/jquery-1-9-1-event-handle-apply-alternative
    // ($.event.dispatch||$.event.handle).call(this, event);
    $.event.special.myDown = {
        setup: function() {
            var isIOS = ((/iphone|ipad/gi).test(navigator.appVersion));
            var myDown = isIOS ? "touchstart" : "mousedown";
            $(this).bind(myDown + ".myDownEvent", function(event) {
                event.type = "myDown";
                ($.event.dispatch||$.event.handle).call(this, event);
            });
        },
        teardown: function() {
            $(this).unbind(".myDownEvent");
        }
    };
    

    【讨论】:

    • 在映射 touchstart 命令以替换 mouseclick 命令时要小心。你失去了点击事件的一项非常有价值的功能。单击后跟一个 touchmove 会取消单击。无论 touchmove 事件如何,一个 touchstart 后跟一个 touchmove 都会触发触摸/单击。所以如果你不小心点击了某个东西,你不能把手指从元素上拖出来来取消点击。
    • @Alex 你是对的,但你可以再次检查touchstarttouchend 上的目标是否相同。并且可以得到event.originalEvent.targetTouches[0].pageXpageY下的pageX和pageY,然后检查手指是否移动。
    • @AndreasAL 不,我知道。但你没有在你的解决方案中提到这一点;-)
    • 从触摸事件处理程序返回 false 会阻止鼠标事件触发。
    • 小心这样的代码。窗口表面支持触摸事件,也支持鼠标。如果用户使用鼠标,触摸事件将永远不会触发。
    【解决方案2】:

    在 iPad/iPod 上使用 UA 嗅探器时要小心。您正在使用这样的解决方案抛弃所有 Android 设备!更好的解决方案是检测触摸支持,它适用于所有移动/平板设备:

    var isTouchSupported = "ontouchend" in document;
    

    【讨论】:

    • 这样的问题是支持鼠标+键盘但也有触摸屏的计算机将支持该​​事件,但它只会在单击屏幕时触发。
    【解决方案3】:

    扩展 H Dog 答案。这是对我有用的代码。

     if (isTouchSupported) {
        $('#playanimationbtn').off("mouseup");
        $('#stopanimationbtn').off("mouseup");
        $('#playanimationbtn').off("mousedown");
        $('#stopanimationbtn').off("mousedown");
        $('#playanimationbtn').off("click");
        $('#stopanimationbtn').off("click");
        document.getElementById("playanimationbtn").addEventListener("touchend", PlayAnimation);
        document.getElementById("stopanimationbtn").addEventListener("touchend", StopAnimation);
    } else {
        $('#playanimationbtn').off("touchstart");
        $('#playanimationbtn').off("touchend");
        $('#playanimationbtn').off("touchmove");
        $('#playanimationbtn').off("touchend");
        $('#playanimationbtn').off("touchleave");
        $('#stopanimationbtn').off("touchstart");
        $('#stopanimationbtn').off("touchend");
        $('#stopanimationbtn').off("touchmove");
        $('#stopanimationbtn').off("touchend");
        $('#stopanimationbtn').off("touchleave");
        document.getElementById("playanimationbtn").addEventListener("click", PlayAnimation);
        document.getElementById("stopanimationbtn").addEventListener("click", StopAnimation);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多