Pointer Events and default browser behaviour

Hello all,

As per my Twitter
exchange<https://twitter.com/jacobrossi/status/362320494843797505> I'm
writing about the implementation of the Pointer Events spec in Internet
Explorer 10, specifically, regarding the mutual exclusivity between
generating Pointer Events and default browser behaviour.

My gripe with this situation is that it prohibits *pass-thru* observation
of events when the event's default behaviour is not prevented.

Consider a situation where an ad is embedded within another through the use
of a wrapping element (pretty common in the advertising space, where the
more common use is an <iframe> element; also, disclaimer, I work for a rich
media ad company <http://www.celtra.com/>). In such a case it would be in
the interest of the user to be able to scroll the page even though the
touch was initiated within the ad container.

In the case of WebKit- and Gecko-based browsers, one can attach event
listeners in the bubble phase to detect interaction, letting the user
scroll unless interacting with a touch-capturing element (carousels and

document.body.addEventListener('touchstart', function(ev) {
  // interaction tracking code, never calling ev.preventDefault()
}, false);

// some component inside the DOM hierarchy
var div = document.querySelector('#carousel');
div.addEventListener('touchmove', function(ev) {
  // prevent scrolling, since we'd like the user to interact
}, false);

Interacting with *#carousel* will block scrolling and will generate touch
events, but detection of interaction elsewhere in the document will still
allow the user to scroll the content and parent page (if there's nowhere to
scroll the <iframe> content, depending on the length of the swipe).

This is where we hit a snag; to provide similar interaction behaviour for
touch using Pointer Events, we have to add the *-ms-touch-action* attribute
to the elements we want to have Pointer Events generated for:

body { -ms-touch-action: none; }

This enables us to listen for events, whether they're mouse, touch or pen

document.body.addEventListener('MSPointerDown', function(ev) {
  // interaction tracking code, no ev.preventDefault();
}, false);

var div = document.querySelector('#carousel');
div.addEventListener('MSPointerMove', function(ev) {
  // no need for ev.preventDefault();
}, false);

The very act of observing Pointer Events on the body without preventing the
default action prevents the user from scrolling the contents. In WebKit and
Gecko-based browsers you can simply prevent default action anywhere within
the capture and bubble phase, but with Pointer Events, you cannot decide on
the fly, relying on explicit user interaction that toggles the CSS
attribute between these modes using other events such as simulated mouse
clicks. Kind of like the "click to play" used in plugin-based games to
enable Pointer Events and escape when you want to conclude interaction.

My question is, is there a way to have both? To be able to passively
monitor touch events within the Pointer Events model without blocking
scrolling? The only other solution that comes to mind is forwarding calls
to various scrolling functions, which is far from ideal and prone to
various glitches.

* <http://about.me/klemen.slavic>
*Sent from my fusion-powered solar dome in geosynchronous orbit.*

Received on Thursday, 1 August 2013 09:20:45 UTC