My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Sunday, October 25, 2009

Android DOM "Finger" Events


This is the Android based device I am talking about and the installed software is version 1.6, apparently with multi-touch support for more recent devices so mine is not the case.

Disclaimer

The reason I am writing this post is my attempt to reproduce the Android OS interface via browser, hilariously possible with every browser except the original one: the WebKit in Android.
Why would I do that? The mouse has been around for ages, thanks Xerox, but later these years we've seen so many touch screen based devices without common mouse pattern. Since I think both Android, iPhone, and others, have done an excellent work with the way we use the device UI I thought: Why not! It could be a great time to start analysis and piece of libraries to replicate in a cross browser way some device independent event. Well, as I've already said, and as you'll see next, right now it is not possible!

Mouse Events .. ahem, Finger Events

Every mouse related event we know does not make much sense with a touchscreen, at least the tested one. Think about it: a finger points something (aka: mousedown) move somewhere (aka: mousemove) remove the finger itself (aka: mouseup). This is not what truly happens.

Mouse Events Order

  • mouseout, optionally fired when point if before we pointed another element
  • mouseover, optionally fired if the pointed event is different (or no elements have been pointed before)
  • mousemove, always before mousedown, sometimes fired twice if the internal cursor is in position 0,0 - this event is not performed while we move the finger!
  • mousedown
  • mouseup
  • click, which is so far the only event that makes sense
  • DOMActivated, a common WebKit "bug"


Mousemove Events ... Whatever ...

Fired events are device dependent, my device fires these events just in order but whatever we change in the DOM wont be called/rendered until we release. Mousemove is fired once, maximum twice, but never during movement.
In few words the only "mouse event" that makes sense is click, not performed if we scroll.

Forget The Drag And Drop!

Even if the most interesting part of the Android interface is the drag and drop, via WebKit mobile we cannot even try to emulate it just because the only event fired while we move the pointer is scroll.

Scroll ... Whatever ...

This event could be considered just a notify and nothing else. If we do whatever action while we scroll a page nothing will happen until we release the pointed element. Accordingly we cannot use the element to synchronize somehow the rendered page since again, nothing will happen during the scroll. The phone browser is basically frozen during the entire lifecycle of a gesture, or a pointer (via finger) operation.

(window || document) // it does not matter
.addEventListener(
"scroll",
(function(i){
return function scroll(e){
// it's a waste of time
// to perform whatever
// action here
// let's speed up things
// adding delay
if(i)
clearTimeout(i);
i = setTimeout(function(){
i = 0;
onScroll();

}, /* about */ 250);
};
})(0)
)
;

Above snippet represents a delayed onScroll event which aim is to be performed faster without slowing down the page while we are scrolling.
I know this could sound a nonsense but operation will be performed in any cases but never rendered so why should we let our phone compute stuff will never be showed?
Also a scroll could be not perfect, since the mouse wheel won't be there and a pointer has 10 pixels of tolerance so just wait the end of the action, and only at that point perform something.

Resize

Both window or document, no difference in this case, will always perform a resize event. This is the last reliable event we have so far in a G1 device.

Drop Down Menu Not Worth It

Common JavaScript drop down menu usually activated via mouseover and removed on mouseout won't work as expected in common touchscreens while if we implement a "clever" click manager Desktop users will be a bit disoriented 'cause we failed implementing these menus everywhere just because these are strictly device pointer dependent, so not re-adaptable/usable at all.
Moreover, a finger is not a mouse and it's more complicated to click the right menu/link at first shot. We need to rethink a little bit the UI if our aim is to make a website usable, without having 2 versions to maintain, with both desktop and mobile or touchscreen.

As Summary

We have basically 3 events, and few others, such onload, DOMContentLoaded, focus and key related for inputs, but these a part other events won't necessarily act as expected.
We need to bear in mind that mousemove or mouseover/out are quite meaningless since there is no mouse and no sensor able to monitor the finger activity when close to the screen. iPhone implemented a touch event but still, touch does not allow drag and drop so if we would like to emulate the Mobile OS interface via the Mobile Browser, we simply cannot: what a joke, but that's how it is.