How to bind both Mousedown and Touchstart, but not respond to both? Android, JQuery

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

preventDefault cancels the event, as per specs

You get touchstart, but once you cancel it you no longer get mousedown. Contrary to what the accepted answer says, you don't need to call stopPropagation unless it's something you need. The event will propagate normally even when cancelled. The browser will ignore it, but your hooks will still work.

Mozilla agrees with me on this one:

calling preventDefault() on a touchstart or the first touchmove event of a series prevents the corresponding mouse events from firing

EDIT: I just read the question again and you say that you already did this and it didn't fix the Android default browser. Not sure how the accepted answer helped, as it does the same thing basically, just in a more complicated way and with an event propagation bug (touchstart doesn't propagate, but click does)


I have been using this function:

//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);

UPDATE: Modified answer to support mouse and touch events together.


taking gregers comment on win8 and chrome/firefox into account, skyisred's comment doesn't look that dumb after all (:P @ all the haters) though I would rather go with a blacklist than with a whitelist which he suggested, only excluding Android from touch-binds:

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: I found that mouse-events are NOT always triggered (if stopPropagation and preventDefault were used), specifically I only noticed an extra mousemove directly before a touchend event... really weird bug but the above code fixed it for me across all (tested OSX, Win, iOS 5+6, Android 2+4 each with native browser, Chrome, Firefox, IE, Safari and Opera, if available) platforms.