2

1) I'm building a very normal HTML5 website.

On this website there are few clickable elements. Those are embedded in multi-layer div.

HAML speaking it looks as :

%body
  #root
    #content
  #header
  #footer

In my div #content I have few clickable buttons. Some dragable elements. And video players.

-> this make use of mouse events as click, mousemove, mouseenter ...

2) I'm adding a touch gesture detection

Everything is fine until I want to add a layer (a div) to catch touch gestures.

Then I obtains this :

%body
  #root
    #content
  #header
  #footer
  #touch-area

This #touch-area size of the window is capable to interpret user touch gesture via touchstart, touchmove, touchstop

3) cool! but I'm loosing control of mouse events

The issue with this construction is all mouse events are caught by #touch-area

I've tried few «hacks»

3.1) via CSS

adding pointer-events: none to #touch-area disable touch event at same time.

3.2) What is it possible in JS?

Reading Click through div . The guy add a click listener to top div. Hide this div. Re-trigger the event. Re-show the div.

It could work but:

  • it use jQuery
  • I've to specify all events I want to let pass trough my #touch-area

3.3) ok, let's focus on mousemove

So I read this post about HTML5 and touchscreen. And I found this interesting event order :

1. touchstart
2. touchmove
3. touchend
4. mouseover
5. mousemove
6. mousedown
7. mouseup
8. click 

And I though:

  • First I add mousemove listenner to #touch-area. Where I hide #touch-area.
  • Then all events will go though.
  • And on side I add a timeout routine to show #touch-area after few ms. That to catch again touch events.

But... when I swipe on the touchscreen. It first detect few mousemove. Then the sequence touchstart, touchmove, touchstop is fired.

begin log of event on #touch-area when I swipe my finger :

(event name followed by event time)

mouse enter
1490656039478
mouse move
1490656039479
mouse enter
1490656039483
mouse move
1490656039484
touch start
1490656039485
touch move
1490656039492
touch move
490656039498

... then there is only touch move until touch stop

so my plan is broken :(

4) stackoverflow could you help me?

How to have a top layer capable to catch touch gestures and bellow normal clickable buttons?

Community
  • 1
  • 1
mickro
  • 881
  • 2
  • 11
  • 26
  • mikro, I really appreciate the effort you put into composing your question but, at least for me, it's not really clear what you are asking. And I don't think I should have to read all the resources you linked in order to understand that. Could you please state in clear what you want to achieve? In 20 words, or less? Maybe also provide a [mcve], if you think it could help understand the problem? – tao Mar 27 '17 at 22:13
  • Do you want this [`functionality`](http://stackoverflow.com/a/18642544/1891677) without using jQuery? Would that answer your question? – tao Mar 27 '17 at 22:17
  • I understand. That why I attempt to put a "simple" question at point 4. The complexity is behind what is exposed at point 2. Close enough I believe to "Minimal exemple". To finish I described my tries at point 3. – mickro Mar 27 '17 at 22:20
  • @AndreiGheorghiu, no as it the answer with jQuery will not solve my issue. – mickro Mar 27 '17 at 22:21
  • mikro, can you please re-read my previous question? I specifically asked "without jQuery". If I make a pure js script that on click disables pointer events on `#touch-area`, clicks again in the same spot and than re-enables pointer events on `#touch-area`, that's not going to help you? – tao Mar 27 '17 at 22:24

3 Answers3

1

This will allow clicks to pass through #touch-area, without using jQuery:

let touchArea = document.getElementById('touch-area');
touchArea.onclick = function(e){
  touchArea.style.display = 'none';
  document.elementFromPoint(e.clientX, e.clientY).click();
  touchArea.style.display = 'block';
  return false;
}

Working example. While it works for clicks, having it work for hover is a completely different matter and frankly, I have no idea on how you could achieve that.

tao
  • 82,996
  • 16
  • 114
  • 150
  • nice :) But that's not including hover events which are showing to user what is clickable via the pointer and sometime with visual emphasis. That's why I was more focusing on `mousemove`. Anyway so far the best option. Thanks. – mickro Mar 27 '17 at 22:58
0

Why not simply check the device for touch support, and only then insert the #touch-area div dynamically?

My goto solution for evaluating if a device supports feature x is https://modernizr.com/.

Here's a quick intro to using Modernizr to identifying the devices that support touch events, and those that don't: http://www.hongkiat.com/blog/detect-touch-device-modernizr/

  • I do not add #touch-aera dynamically for touch device because all "tap"/"click" are described layers below. And I need it even with touch devices. But the idea is there. I attempted to hide #touch-area when it not a specific gesture (swipe, pan). – mickro Mar 27 '17 at 22:22
-1

You have to use the preventDefault() method in the touch event handlers.

Supporting Touch and Mouse event

pushkin
  • 9,575
  • 15
  • 51
  • 95
sumana
  • 21
  • 4