Touch

Chances are if you're making a modern website you're going to make life nice and tactile for mobile users. I try anyway. So I wrote a pretty simple script which allowed you to open and close an off-canvas menu by swiping sideways (see our site for reference). Then a client came along with a Windows phone and ruined my day.

Why the **** won't you work?!

I should start off by saying it's fixed now. Webkit, Mozilla and all the other non-Microsoft browsers use the standard events you'd expect: touchstart, touchmove and touchend. They take a little bit of getting your head around at first because each event returns an object containing numerous variables. Why? Because it supports multiple fingers simultaneously. In most browsers you'd write something like this:

  1. viewport = document.getElementById("viewport");
  2. viewport.addEventListener("touchstart", begin, false);
  3. var begin = function(event) {
  4. startX = event.touches[0].pageX;
  5. startY = event.touches[0].pageY;
  6. // Do something with it
  7. };

"touches[0]" gets the first finger in contact with the screen FYI.

The problem with IE

I don't like bashing IE. I'll admit some of the older browsers have caused problems to developers everywhere because they don't support new technologies and do things slightly differently. The problem is the people who continue to use the old browsers. Microsoft actually held a funeral for IE6 and some people continue to use it. But the real root of the problem is the fact that old IE doesn't automatically update. I know for a fact my version of Chrome will be the most recent at all times.

But I'm off on a tangent there.

Microsoft

Windows 8 is pretty good in my opinion. It's very tactile, easy to pick up and use and definitely a step in the right direction. It's almost identical across desktop, browser and tablet which is something web designers and developers are striving towards with their sites. In order to keep the experience the same across all devices they made it so that touch, a stylus and your mouse pointer all do pretty much the same thing. So far so good. Then in IE they gave the events that handle it a different name and the return objects are more like those of a mouse. In fact the three corresponding events are pointerdown, pointermove and pointerup. SO close. This is how it's done:

  1. viewport = document.getElementById("viewport");
  2. viewport.addEventListener("pointerdown", begin, false);
  3. var begin = function(event) {
  4. startX = event.clientX;
  5. startY = event.clientY;
  6. // Again, do something here
  7. };

As you can see - it's pretty similar.

Putting it all together

Handily, you can easily use Javascript to check whether you're using an IE pointer event driven device.

  1. if (window.navigator.pointerEnabled) {
  2. //
  3. };

So, below is a simple bit of code which combines the two. Also, because I've not covered the move and end states I'll include them as well:

  1. var ms = false; // boolean for Microsoft or not
  2. var startX,startY,moveX,moveY = 0; // a few integers
  3. var viewport; // our touch handling div
  4. window.onload = function() {
  5. viewport = document.getElementById('viewport');
  6. if (window.navigator.pointerEnabled) {
  7. ms = true;
  8. viewport.addEventListener("pointerdown", begin, false);
  9. viewport.addEventListener("pointermove", moving, false);
  10. viewport.addEventListener("pointerup", up, false);
  11. } else {
  12. viewport.addEventListener("touchstart", begin, false);
  13. viewport.addEventListener("touchmove", moving, false);
  14. viewport.addEventListener("touchend", up, false);
  15. };
  16. };

In theory, you could ignore the ms boolean and bind the Pointer and Touch events to different functions. I haven't because you end up with twice as many functions and it doesn't feel particularly clean. Now the handler functions:

  1. var begin = function(event) {
  2. if (ms) {
  3. startX = event.clientX;
  4. startY = event.clientY;
  5. } else {
  6. startX = event.touches[0].pageX;
  7. startY = event.touches[0].pageY;
  8. };
  9. };
  10. var moving = function(event) {
  11. if (ms) {
  12. moveX = event.clientX;
  13. moveY = event.clientY;
  14. } else {
  15. moveX = event.changedTouches[0].pageX;
  16. moveY = event.changedTouches[0].pageY;
  17. };
  18. // do something
  19. };
  20. var up = function() {
  21. // End handler
  22. };

You can then compare moveX with startX and likewise for Y as the user moves their finger, stylus or left-click-held-down mouse and use the information to do whatever you want.

Remember that the pointerup and touchend events don't return values as in theory they have no location. If you want to know the last position that was touched it'll be stored in the moveX and moveY variables which I deliberately declared globally for that very reason.

In summary

I hope by reading this I just saved you a few hours research. It's not really that hard if you know your Javascript. Good luck and feel free to comment.