How to bind 'touchstart' and 'click' events but not respond to both?

前端 未结 30 3385
抹茶落季
抹茶落季 2020-11-22 14:08

I\'m working on a mobile web site that has to work on a variety of devices. The one\'s giving me a headache at the moment are BlackBerry.

We need to support both key

30条回答
  •  独厮守ぢ
    2020-11-22 14:33

    EDIT: My former answer (based on answers in this thread) was not the way to go for me. I wanted a sub-menu to expand on mouse enter or touch click and to collapse on mouse leave or another touch click. Since mouse events normally are being fired after touch events, it was kind of tricky to write event listeners that support both touchscreen and mouse input at the same time.

    jQuery plugin: Touch Or Mouse

    I ended up writing a jQuery plugin called "Touch Or Mouse" (897 bytes minified) that can detect whether an event was invoked by a touchscreen or mouse (without testing for touch support!). This enables the support of both touchscreen and mouse at the same time and completely separate their events.

    This way the OP can use touchstart or touchend for quickly responding to touch clicks and click for clicks invoked only by a mouse.

    Demonstration

    First one has to make ie. the body element track touch events:

    $(document.body).touchOrMouse('init');
    

    Mouse events our bound to elements in the default way and by calling $body.touchOrMouse('get', e) we can find out whether the event was invoked by a touchscreen or mouse.

    $('.link').click(function(e) {
      var touchOrMouse = $(document.body).touchOrMouse('get', e);
    
      if (touchOrMouse === 'touch') {
        // Handle touch click.
      }
      else if (touchOrMouse === 'mouse') {
        // Handle mouse click.
      }
    }
    

    See the plugin at work at http://jsfiddle.net/lmeurs/uo4069nh.

    Explanation

    1. This plugin needs to be called on ie. the body element to track touchstart and touchend events, this way the touchend event does not have to be fired on the trigger element (ie. a link or button). Between these two touch events this plugin considers any mouse event to be invoked by touch.
    2. Mouse events are fired only after touchend, when a mouse event is being fired within the ghostEventDelay (option, 1000ms by default) after touchend, this plugin considers the mouse event to be invoked by touch.
    3. When clicking on an element using a touchscreen, the element gains the :active state. The mouseleave event is only fired after the element loses this state by ie. clicking on another element. Since this could be seconds (or minutes!) after the mouseenter event has been fired, this plugin keeps track of an element's last mouseenter event: if the last mouseenter event was invoked by touch, the following mouseleave event is also considered to be invoked by touch.

提交回复
热议问题