Dirtiest. Hack. Ever. iOS Event Delegation Solved(?)

So, iOS Safari has a problem with javascript event delegation.

Normally you click (or trigger any event) on an element, and the browser traverses back up the dom, triggering that event on each parent. Thus we can attach an event listener to a ul, and all it li’l children (and bastard offspring) will inherit the same listener.

Possibly for memory management reasons, this doesn’t happen in iOS Safari – unless the element is a link or input – an actual ‘clickable’ element. So there is some logic here, but we’re in a different age and this kind of behaviour is completely at odds with all other browsers, which screws us pretty bad as so much of our application behaviour today relies on event delegation.

There is a fix – if Safari thinks you want your element to be interactive, it will allow delegation – give the element the css property of cursor:pointer;

Ok, fine if you have a specific element which needs delegation, but what if you have an element with lots of children? What a waste, adding the cursor property to all that CSS.

And what if you need to do something very generic? We need to emulate rollover behaviour with touch sometimes, so we want to touch open a menu, and close on touch off. We can’t possibly know which element a user will ‘touch off’ on. If a modal effect is desired, that’s easy – our modal layer is a single element we can add the cursor to. But if we want a touch off action to be able to trigger another element, as well as trigger our mouseout-like behaviour, that’s no good.

Greedy Bastard Ahoy!

Obviously we can’t simply give cursor:pointer; to everything, I mean, the cursor MEANS something.

Or can we? There IS no cursor on iDevices. All we need do is determine when we are on a device, say with Modernizr [new window], and away we go…

 

Dirty. Greedy. Lazy. Bastard.
But it works.
Now, touch isn’t a perfect answer here – there are touch devices that support input peripherals, and a touch PC with a mouse would be a bit borked, as they would have a constant pointer – but there are refinements. User Agent sniffing is a bit dodgy, but c’mon, iOS users changing their user agent? And frankly, if you change your user agent, you should expect things to behave oddly.

https://gist.github.com/855078

Of course, if memory usage was SUCH a problem that Apple engineers simply HAD to disable event delegation in the first place, then we have just reopened that can of worms – into our pants, before diving into a piranha pool – so it is probably best to excercise caution…

[edit] An invisible modal underlay  to catch click off for such elements would solve this – though that can be difficult to implement in some layout situations, and also interferes with interaction with other elements [/edit]

Leave a Reply

Your e-mail address will not be published. Required fields are marked *