4

Making a nice quick-responding website is relatively difficult because of the conflicts between touchstart, tap and the 300ms delayed click.

Ofcourse vclick should fix these issues, but also they seem to have problems fixing it completely. From the documentation:

Warning: Use vclick with caution

Use vclick with caution on touch devices. Webkit based browsers synthesize mousedown, mouseup, and click events roughly 300ms after the touchend event is dispatched. The target of the synthesized mouse events are calculated at the time they are dispatched and are based on the location of the touch events and, in some cases, the implementation specific heuristics which leads to different target calculations on different devices and even different OS versions for the same device. This means the target element within the original touch events could be different from the target element within the synthesized mouse events.

We recommend using click instead of vclick anytime the action being triggered has the possibility of changing the content underneath the point that was touched on screen. This includes page transitions and other behaviors such as collapse/expand that could result in the screen shifting or content being completely replaced.

Now I'm thinking about doing something simpler. Whenever a touchstart event is being triggered I know this is a touch device for sure. I just disable all click events, and start listening to touchstart (or tap) events only. Ignoring the 300ms delayed click events.

Of course there are devices with a mouse and touch, but people using these at the same time seem like a minority to me.

Is this a good idea, or am I missing something in my thinking?

Dirk Boer
  • 8,522
  • 13
  • 63
  • 111
  • I think it is fine to use an opening screen to detect if touch events are available, but has some drawbacks in terms of UX. For example if the user touches the screen but do not remove the finger you may already have been triggered the event and as you have suggested listening to tap events is better. I personally use a custom click/touch wrapper for this purpose. It detects touch start if it is available and manages touchstart/move/end accordingly. – Ali Naci Erdem Dec 16 '14 at 08:41
  • Touchscreen laptops are becoming the norm in Windows world, so you need to be careful not to break your site for those users. – OlliM Dec 16 '14 at 12:06

4 Answers4

2

First of… what makes you say that people that use both touch and mouse input are a minority?

The 300ms click delay has been gone a while now on Android when using <meta name="viewport" content="width=device-width">. Unfortunately it can't be removed on iOS because it's a scroll gesture on unzoomable pages that almost nobody seems to be aware of.

I'd say that the best approach is still to support both mouse as well as touch input, despite the 300ms delay on iOS devices. It's dangerous to assume a user will exclusively use touch input when they use it once.

Imagine a user happily using a mouse to navigate. They see something interesting that they want to look at a bit closer so they use a touch gesture to zoom in and all of a sudden mouse clicks don't work anymore. That sounds broken to me.

I just remembered an interesting discussion about detecting a mouse user. Maybe it'll help you see things a bit differently.

Matijs
  • 3,118
  • 2
  • 29
  • 41
  • That people with a mouse and touch is a minority (at this moment) is quite some common sense. At least here in the Netherlands. I know exactly 0 people with a screen that supports touch and are commonly used with a mouse. From the people that I know almost everyone has a smartphone, and almost everyone has a desktop or normal laptop (without touch). Doesn't mean they don't exist. Just means they are a minority. Like IE7 users that I also don't support. – Dirk Boer Dec 23 '14 at 11:57
  • ps. 300ms delay for something that has to feel native I can't live with for this application. – Dirk Boer Dec 23 '14 at 12:02
1

Yes, in my honest opinion it is smart way to go. This has proven to be quite a hard problem and when you still combine it to the compatibility problems caused by some really crappy mobile devices which don't follow standards even that bit, it quickly becomes a battle that you can't win. We have adopted a solution close to this, with realization of fact that there might arise problems with poor devices. But after all, you can't satisfy the needs of everybody and the distribution of usage tends to favor those devices (nowadays) that follow the standards.

Also note that you don't need to wait for first touchstart to happen. Instead you can do this trick after DOM is ready and bind the events accordingly.

var isTouchDevice = 'ontouchstart' in document.documentElement;

which is copied from KevBurnsJr's answer.

Also as you most probably already know, you can bind to all kind of events and then check when entering the callback of which type the event actually is with

event.type

Good luck!

Community
  • 1
  • 1
Roope Hakulinen
  • 7,326
  • 4
  • 43
  • 66
  • Hi Sanfor, thanks for your answer. The thing is that detecting touch capability is not the same as really knowing that the user will use touch. – Dirk Boer Dec 18 '14 at 10:51
  • That is true, for which reason, you can still use the _event.type_ to correct the assumption made based on _isTouchDevice_. – Roope Hakulinen Dec 18 '14 at 10:57
  • 1
    `'ontouchstart' in document.documentElement` does not mean it's a touch only device. It only detects supports for the Touch Evens API. You can't and shouldn't assume what the user will be using based on Touch capability alone. – hexalys Dec 22 '14 at 10:59
1

It would be a bad idea to disable all click events on the basis of a single touchstart as you suggest. While using both pointers or touch at the same time isn't a common use case. Preventing dual use of mouse/pens and touch isn't a forward compatible approach.

And when you say: "Ignoring the 300ms delayed click events."

I think you make a false assumption on click. You'd still have to synthesize clicks one way or another. touchstart alone isn't a click action. An assumed click happens on touchend, not touchstart. Here is the principle behind detecting clicks early on mobile: https://developers.google.com/mobile/articles/fast_buttons

If you are looking for fastclicks you may want to look into the fastclick script or other fastclick ones on github instead of vclicks.

hexalys
  • 5,177
  • 3
  • 31
  • 56
0

To avoid issues with people using both touchscreen and mouse with pleasant reactivity I suggest this in JQuery, it works good enough for me:

$elem.on('click touchstart', function(e){
   var $self = $(this);
   if(e.type == 'touchstart'){ 
      $self.mouseenter(); //fire events you still need 
      e.preventDefault();
   }
   /* your code */
});

From my experience it's better than keep the delay on click event and some hazardous comportment through devices, but there's inconvenient too.

On the iPad I tested, it avoids the situation where hover event is triggered on first tap then click event on second tap, but also it seems that the click event fire when you tap near the border of your element and not the touchstart, have to keep it in mind.

Also, it seems not working well with 'tap' event, certainly because it's not well treated yet by JQuery.