如何绑定Mousedown和Touchstart,但不同时响应? Android,JQuery

时间:2012-12-01 03:00:20

标签: javascript android jquery

在可在移动设备上查看的网站上工作,需要在touchstart和mousedown上绑定操作。

看起来像这样

 $("#roll").bind("mousedown touchstart", function(event){

 someAction();

它在Iphone上工作正常,但在Android上它会响应两次。

event.stopPropagation();
event.preventDefault();

添加此代码会修复Android Chrome,但不适用于Android默认浏览器。任何其他技巧可以解决所有Android的问题?

9 个答案:

答案 0 :(得分:26)

我一直在使用这个功能:

//touch click helper
(function ($) {
    $.fn.tclick = function (onclick) {

        this.bind("touchstart", function (e) { 
            onclick.call(this, e); 
            e.stopPropagation(); 
            e.preventDefault(); 
        });

        this.bind("click", function (e) { 
           onclick.call(this, e);  //substitute mousedown event for exact same result as touchstart         
        });   

        return this;
    };
})(jQuery);

更新:修改了答案以支持鼠标和触摸事件。

答案 1 :(得分:24)

element.on('touchstart mousedown', function(e) {
    e.preventDefault();
    someAction();
});

preventDefault取消活动as per specs

你得到 touchstart ,但是一旦你取消它就不再获得 mousedown 了。与接受的答案相反,除非您需要,否则不需要致电stopPropagation。即使取消,事件也会正常传播。浏览器将忽略它,但你的钩子仍然可以工作。

Mozilla agrees with me就此而言:

  

在touchstart上调用preventDefault()或者系列的第一个touchmove事件会阻止相应的鼠标事件触发

编辑:我刚刚再次阅读了这个问题,你说你已经这样做了,并没有修复Android默认浏览器。不确定接受的答案如何帮助,因为它基本上做同样的事情,只是以更复杂的方式和事件传播错误(touchstart不传播,但点击确实)

答案 2 :(得分:3)

考虑到对win8和chrome / firefox的评论,天空的评论看起来并不那么愚蠢(:P @ all haters) 虽然我宁愿选择黑名单,也不愿意使用他建议的白名单,但只能将Android排除在触控状态之外:

var ua = navigator.userAgent.toLowerCase(),
isAndroid = ua.indexOf("android") != -1,
supportsPointer = !!window.navigator.msPointerEnabled,
ev_pointer = function(e) { ... }, // function to handle IE10's pointer events
ev_touch = function(e) { ... }, // function to handle touch events
ev_mouse = function(e) { ... }; // function to handle mouse events

if (supportsPointer) { // IE10 / Pointer Events
    // reset binds
    $("yourSelectorHere").on('MSPointerDown MSPointerMove MSPointerUp', ev_pointer);
} else {
    $("yourSelectorHere").on('touchstart touchmove touchend', ev_touch); // touch events
    if(!isAndroid) { 
        // in androids native browser mouse events are sometimes triggered directly w/o a preceding touchevent (most likely a bug)
        // bug confirmed in android 4.0.3 and 4.1.2
        $("yourSelectorHere").on('mousedown mousemove mouseup mouseleave', ev_mouse); // mouse events
    }
}
BTW:我发现鼠标事件并不总是被触发(如果使用了stopPropagation和preventDefault),特别是我在touchend事件之前只注意到一个额外的鼠标移动...真的很奇怪但上面的代码为我修复了它所有(经过测试的OSX,Win,iOS 5 + 6,Android 2 + 4,每个都有原生浏览器,Chrome,Firefox,IE,Safari和Opera,如果有的话)平台。

答案 3 :(得分:2)

使用此代码修复

var mobile   = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); 
var start = mobile ? "touchstart" : "mousedown";
$("#roll").bind(start, function(event){

答案 4 :(得分:2)

我认为最好的方法是:

var hasTouchStartEvent = 'ontouchstart' in document.createElement( 'div' );

document.addEventListener( hasTouchStartEvent ? 'touchstart' : 'mousedown', function( e ) {
    console.log( e.touches ? 'TouchEvent' : 'MouseEvent' );
}, false );

答案 5 :(得分:0)

我建议你试试jquery-fast-click。我在这个问题和others上尝试了另一种方法。每个固定的一个问题,并介绍另一个。第一次在Android,ios,桌面和桌面触摸浏览器上快速点击工作(呻吟)。

答案 6 :(得分:0)

编写此代码并添加j查询打孔触摸js.it将使用触摸事件模拟鼠标事件

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
         switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type="mousemove"; break;        
        case "touchend":   type="mouseup"; break;
        default: return;
    }

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                              first.screenX, first.screenY, 
                              first.clientX, first.clientY, false, 
                              false, false, false, 0/*left*/, null);
    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() 
{
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);    
} 

答案 7 :(得分:0)

这种原生解决方案最适合我:

  1. touchstart事件添加到文档设置全局touch = true
  2. 在mousedown / touchstart处理程序中,在检测到触摸屏时阻止所有mousedown事件:if (touch && e.type === 'mousedown') return;

答案 8 :(得分:0)

哇,在这个问题和相关问题中有这么多答案,但没有一个对我有用(Chrome,移动响应,mousedown + touchstart)。但这:

(e) => {
  if(typeof(window.ontouchstart) != 'undefined' && e.type == 'mousedown') return;

  // do anything...
}