3

My problem is I cannot cancel the mousedown event that's fired after touchstart has been triggered. This problem is specific to Android's native browser.

Chrome and Safari both successfully execute my method below in both Android and iOS (onMenuInteraction). My problem seems to be confined to Android's native browser (for me that's preinstalled with Android 4.1.2).

The following is code that I've extracted from my Javascript object.

MenuButtonView.prototype.onSmallScreenSetUp = function() {
    $("#mobileMenuBtn").on( { "touchstart mousedown": $.proxy( this.onMenuInteraction, this ) } );
}

MenuButtonView.prototype.onMenuInteraction = function(e) {
    console.log( this, "onMenuInteraction", e );
    e.stopImmediatePropagation();
    e.stopPropagation();
    e.preventDefault();
}

Please could someone tell me how I can cancel the mousedown event that's fired after your finger touches the screen triggering the touchstart event.

This requirement is based on managing interaction with both desktop and mobile / tablet platforms. Everything works until you're testing with the Android native browser.

Many thanks

D

user2190690
  • 1,744
  • 4
  • 24
  • 31

4 Answers4

10

check for presence of touchstart support, set a variable to determine what support you provide:

//touchstart or mousedown
var click = ('ontouchstart' in document.documentElement)  ? 'touchstart' : 'mousedown';

then use:

$(element).on(click,function(){
    //do stuff
}); 

note that click in this instance is a variable, not a string.

dewd
  • 4,380
  • 3
  • 29
  • 43
  • 3
    How does this work on newer laptops with both touchscreens and mice? – Alec Jul 21 '16 at 15:41
  • 1
    I think they use touchstart but they respond to mouse inputs like a touch. I tested this a few months ago and I'm sure that's what happened. I don't have access to such a device to test now though. I do remember what I was building at the time had to pass the MS Surface test and it did. – dewd Jul 21 '16 at 15:47
  • @CandleCoder what's the OS and browser? I tested on MS Surface (1 1/2 years ago) and it worked. – dewd Nov 10 '16 at 14:15
  • Asus chromebook – CandleCoder Nov 10 '16 at 14:16
  • @CandleCoder browser? – dewd Nov 10 '16 at 14:23
  • Chrome app (Chromebook) – CandleCoder Nov 10 '16 at 14:25
  • Unfortunately, I don't have a Chromebook to test on and emulators are usually unreliable. It's going to be a case of reverse engineering it, and then trying to make it x-device/ browser compatible. Have you tried doing either on it's own, e.g. just touchstart or mousedown? How does the device respond to each on its own? – dewd Nov 10 '16 at 14:31
3

Use e.preventDefault(); to cancel mousedown event if touchstart was triggered.

Aleks Dorohovich
  • 1,622
  • 1
  • 13
  • 17
  • 1
    The only solution that works! Other people don't understand because they don't have a laptop with both touchscreen and mouse (e.g. Chromebook) Thanks! – FlorianB May 27 '19 at 18:10
1
  1. Detect which events are supported - no need to support both events simultaneously
  2. load $.on() accordingly
  3. before adding events remove all events so propagated and/or pre-existing(unwanted) events do not becoming an issue

    $("#mobileMenuBtn").off().on( { "touchstart mousedown": $.proxy( this.onMenuInteraction, this ) } );

References:

how-to-check-browser-for-touchstart-support-using-js-jquery

jquery:off()

Community
  • 1
  • 1
JDA
  • 61
  • 5
  • 1
    Re #1 that's not true in general, a device can have both a touch screen and a mouse device. For example, a Chromebook or Windows touchscreen tablet/notebook. If this is an Android app (e.g. embedded in Phonegap/Cordova) then you could assume just touch events and skip mouse entirely. If it's a web page you can't assume that since it could be visited in several different browsers including desktop. Try this: http://stackoverflow.com/questions/13655919/how-to-bind-both-mousedown-and-touchstart-but-not-respond-to-both-android-jqu – Dave Methvin Aug 27 '14 at 22:24
  • he was referring specifically to Android and i was answering his android question ;) and i agree, depending on a given environment you may need to do things differently. – JDA Aug 28 '14 at 12:35
1

Using a combination of advice above from JDA and Dave Methvin (thank you to both), the solution to my question is below.

In the callback for the "touchstart mousedown" event I switch off specifically "touchstart mousedown". This stops any subsequent touch or mouse event being called.

I've found implementing 'touchend' problematic with Android's native browser - however 'mouseup' event seems to cover both purposes well, i.e, to me it seems to behave in the same way as you would expect 'touchend'.

When 'mouseup' is called I then reapply the "touchstart and mousedown" events to the button.

A simplified version of my solution is below:

$(document).ready( function() {

        $("#mobileMenuBtn").on( { "touchstart mousedown" : onInteraction,
                                  "mouseup" : onInteractionEnd } );

        function onInteraction(e) {
            $("#mobileMenuBtn").off( "touchstart mousedown" );
        }

        function onInteractionEnd(e) {
            $("#mobileMenuBtn").on( { "touchstart mousedown" : onInteraction } );
        }

})

Hope this helps others that find the same problem.

user2190690
  • 1,744
  • 4
  • 24
  • 31