Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document defines events and related interfaces for handling hardware agnostic pointer input from devices like a mouse, pen, or touchscreen. For compatibility with existing mouse-based content, this specification also describes a mapping to fire [DOM-LEVEL-3-EVENTS] Mouse Events for pointer device types other than mouse.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Pointer Events Working Group as a Last Call Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-pointer-events@w3.org (subscribe, archives). The Last Call period ends 19 March 2013. All comments are welcome.
This document is based on a previous Member Submission by Microsoft Corporation with changes made based on the consensus of the Working Group. Current bugs and issues are managed in Bugzilla.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This is a Last Call Working Draft and thus the Working Group has determined that this document has satisfied the relevant technical requirements and is sufficiently stable to advance through the Technical Recommendation process.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
PointerEvent
Interfacepointerdown
eventpointerup
eventpointercancel
eventpointermove
eventpointerover
eventpointerout
eventpointerenter
eventpointerleave
eventgotpointercapture
eventlostpointercapture
eventElement
interfaceNavigator
interfaceThis section is non-normative.
Today, most [HTML5] content is used with and/or designed for mouse input. Those that handle input in a custom manner typically code to [DOM-LEVEL-3-EVENTS] Mouse Events. Newer computing devices today, however, incorporate other forms of input, like touchscreens or pen input. Event types have been proposed for handling each of these forms of input individually. However, that approach requires a step function in opportunity cost to authors when adding support for a new input type. This often creates a compatibility problem when content is written with only one device type in mind. Additionally, for compatibility with existing mouse-based content, most user agents fire Mouse Events for all input types. This makes it ambiguous whether a Mouse Event represents an actual mouse device or is being produced from another input type for compatibility, which makes it hard to code to both device types simultaneously.
To reduce the cost of coding to multiple input types and also to help with the above described ambiguity with Mouse Events, this specifications defines a more abstract form of input, called a pointer. A pointer can be any point of contact on the screen made by a mouse cursor, pen, touch (including multi-touch), or other pointing input device. This model makes it easy to write sites and applications that work well no matter what hardware the user has. For scenarios when device-specific handling is desired, this specification also defines properties for inspecting the device type which produced the event. The primary goal is to provide a single set of events and interfaces that allow for easy authoring for cross-device pointer input while still allowing for device-specific handling when necessary. An additional key goal is to enable multi-threaded user agents to handle default touch actions, such as scrolling, without blocking on script execution.
The events for handling generic pointer input look a lot like those for mouse: pointerdown, pointermove, pointerup, pointerover, pointerout, etc. This facilitates easier content migration from Mouse Events to Pointer Events. Pointer Events provide all the usual properties present in Mouse Events (client coordinates, target element, button states, etc.) in addition to new properties for other forms of input: pressure, contact geometry, tilt, etc. So authors can easily code to Pointer Events to share logic between different input types where it makes sense, and customize for a particular type of input only where necessary to get the best experience.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].
PointerEvent
Interface[Constructor(DOMString type, optional PointerEventInit eventInitDict)]
interface PointerEvent : MouseEvent {
readonly attribute long pointerId;
readonly attribute long width;
readonly attribute long height;
readonly attribute float pressure;
readonly attribute long tiltX;
readonly attribute long tiltY;
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
};
pointerId
of type long, readonlyA unique identifier for the pointer causing the event. This identifier must be unique from all other active pointers at the time. A user agent may recycle previously retired values for pointerId
from previous active pointers, if necessary.
If the device producing the event is a mouse, then the pointerId
must be 1. Device types other than mouse must not have a pointerId
of 1.
width
of type long, readonlyheight
of type long, readonlypressure
of type float, readonlytiltX
of type long, readonlyThe plane angle (in degrees, in the range of [-90,90]) between the Y-Z plane and the plane containing both the transducer (e.g. pen stylus) axis and the Y axis. A positive tiltX
is to the right. tiltX
can be used along with tiltY
to represent the tilt away from the normal of a transducer with the digitizer. For devices that do not report tilt, the value must be 0.
tiltY
of type long, readonlytiltY
is towards the user. tiltY
can be used along with tiltX
to represent the tilt away from the normal of a transducer with the digitizer. For devices that do not report tilt, the value must be 0.
pointerType
of type DOMString, readonlyIndicates the device type that caused the event (mouse, pen, touch, etc.). If a user agent is to fire a pointer event for a mouse, pen stylus, or touch input device, then the value of pointerType
must be according to the following table:
Pointer Device Type | pointerType Value |
---|---|
Mouse | mouse |
Pen Stylus | pen |
Touch Contact | touch |
If the device type cannot be detected by the user agent, then the value must be an empty string. If a user agent supports pointer device types other than those listed above, the value of pointerType
should be vendor prefixed to avoid conflicting names for different types of devices. Future specifications may provide additional normative values for other device types.
isPrimary
of type boolean, readonlyIn a multi-pointer (e.g. multi-touch) scenario, the primary pointer is used to identify a master pointer amongst the set of active pointers. This pointer is the one that will produce compatibility mouse events. It is also useful when single-pointer interaction is desired by an author.
The primary pointer is indicated on events by a value of true
for the isPrimary
property.
pointerdown
event was dispatched when no other active pointers representing touch input existed.pointerdown
event was dispatched when no other active pointers representing pen input existed.false
for isPrimary
.PointerEvent
Constructordictionary PointerEventInit : MouseEventInit {
long pointerId = 0;
long width = 0;
long height = 0;
float pressure = 0;
long tiltX = 0;
long tiltY = 0;
DOMString pointerType = "";
boolean isPrimary = false;
};
PointerEventInit
MemberspointerId
of type long, defaulting to 0
pointerId
property of the PointerEvent
object.width
of type long, defaulting to 0
width
property of the PointerEvent
object.height
of type long, defaulting to 0
height
property of the PointerEvent
object.pressure
of type float, defaulting to 0
pressure
property of the PointerEvent
object.tiltX
of type long, defaulting to 0
tiltX
property of the PointerEvent
object.tiltY
of type long, defaulting to 0
tiltY
property of the PointerEvent
object.pointerType
of type DOMString, defaulting to ""
pointerType
property of the PointerEvent
object.isPrimary
of type boolean, defaulting to false
isPrimary
property of the PointerEvent
object.PointerEventInit
dictionary is used by the PointerEvent
interface's constructor to provide a mechanism by which to construct untrusted (synthetic) pointer events. It inherits from the MouseEventInit
dictionary defined in [UI-EVENTS]. See the examples for sample code demonstrating how to dispatch an untrusted pointer event.This section is non-normative.
The following table provides a summary of the event types defined in this specification.
Event Type | Sync/Async | Bubbles | Cancellable | Trusted proximal event target types | Event object interface | Default Action |
---|---|---|---|---|---|---|
pointerdown |
Sync | Yes | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of the mousedown event plus dispatch of compatibility mouse events |
pointerup |
Sync | Yes | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mouseup |
pointercancel |
Sync | Yes | Yes | Document , Element |
PointerEvent |
None |
pointermove |
Sync | Yes | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mousemove |
pointerover |
Sync | Yes | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mouseover |
pointerout |
Sync | Yes | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mouseout |
pointerenter |
Sync | No | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mouseenter |
pointerleave |
Sync | No | Yes | Document , Element |
PointerEvent |
Varies: when the pointer is primary, all default actions of mouseleave |
gotpointercapture |
Async | Yes | No | Element |
PointerEvent |
None |
lostpointercapture |
Async | Yes | No | Element |
PointerEvent |
None |
pointerdown
eventA user agent must dispatch this event when a pointer enters the active buttons state. For mouse, this is when the device transitions from no buttons depressed to at least one button depressed. For touch, this is when physical contact is made with the digitizer. For pen, this is when the stylus makes physical contact with the digitizer.
For input devices that do not support hover, a user agent must also fire a pointerover
event preceding the pointerdown
event.
Authors can prevent the production of compatibility mouse events by cancelling the pointerdown
event (if the isPrimary
property is true
).
pointerdown
and pointerup
are dispatched differently than mousedown
and mouseup
. See chorded buttons for more information.pointerup
eventFor input devices that do not support hover, a user agent must also fire a pointerout
event after firing the pointerup
event.
pointerdown
and pointerup
are dispatched differently than mousedown
and mouseup
. See chorded buttons for more information.pointercancel
eventpointerdown
event, the pointer is subsequently used to manipulate the page viewport (e.g. panning or zooming).A user agent must also fire a pointerout
event after firing the pointercancel
event.
This section is non-normative.
Examples of scenarios in which a user agent might determine that a pointer is unlikely to continue to produce events include:
Methods for changing the device's screen orientation, recognizing accidental input, or using a pointer to manipulate the viewport (e.g. panning or zooming) are out of scope for this specification.
pointermove
eventwidth
and height
).pointerover
eventpointerdown
event for devices that do not support hover.pointerout
eventpointerup
event for a device that does not support hoverpointercancel
eventpointerenter
eventpointerdown
event from a device that does not support hover. This event type is similar to pointerover
, but differs in that it does not bubble.mouseenter
event described in [DOM-LEVEL-3-EVENTS], and the CSS :hover
pseudo-class described in [CSS21]. See also the pointerleave
event.pointerleave
eventpointerup
event from a device that does not support hover. This event must also dispatch when a pen stylus leaves hover range detectable by the digitizer. This event type is similar to pointerout
, but differs in that it does not bubble and that it must not be dispatched until the pointing device has left the boundaries of the element and the boundaries of all of its children.mouseleave
event described in [DOM-LEVEL-3-EVENTS], and the CSS :hover
pseudo-class described in [CSS21]. See also the pointerenter
event.gotpointercapture
eventsetPointerCapture()
.lostpointercapture
eventreleasePointerCapture()
.Element
interfacepartial interface Element {
void setPointerCapture (long pointerId);
void releasePointerCapture (long pointerId);
attribute EventHandler onpointerdown;
attribute EventHandler onpointermove;
attribute EventHandler onpointerup;
attribute EventHandler onpointercancel;
attribute EventHandler onpointerover;
attribute EventHandler onpointerout;
attribute EventHandler onpointerenter;
attribute EventHandler onpointerleave;
attribute EventHandler ongotpointercapture;
attribute EventHandler onlostpointercapture;
};
onpointerdown
of type EventHandlerpointerdown
event type.
onpointermove
of type EventHandlerpointermove
event type.
onpointerup
of type EventHandlerpointerup
event type.
onpointercancel
of type EventHandlerpointercancel
event type.
onpointerover
of type EventHandlerpointerover
event type.
onpointerout
of type EventHandlerpointerout
event type.
onpointerenter
of type EventHandlerpointerenter
event type.
onpointerleave
of type EventHandlerpointerleave
event type.
ongotpointercapture
of type EventHandlergotpointercapture
event type.
onlostpointercapture
of type EventHandlerlostpointercapture
event type.
setPointerCapture
Sets pointer capture for the pointer identified by the argument pointerId
to the element on which this method is invoked. Subsequent events for the pointer must always be targeted at this element.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
pointerId | long | ✘ | ✘ |
void
releasePointerCapture
Releases pointer capture for the pointer identified by the argument pointerId
from the element on which this method is invoked. Subsequent events for the pointer follow normal hit testing mechanisms (out of scope for this specification) for determining the event target.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
pointerId | long | ✘ | ✘ |
void
For touch input, the default action of any and all pointer events must not be a manipulation of the viewport (e.g. panning or zooming).
touch-action
CSS propertyName: | touch-action |
---|---|
Value: | auto | none | [pan-x || pan-y ] |
Initial: | auto |
Applies to: | block-level elements, SVG elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | Same as specified value. |
The touch-action
CSS property determines whether touch input may trigger default behavior supplied by user agent. This includes, but is not limited to, behaviors such as panning or zooming.
Values have the following meanings:
auto
or none
values are out of scope for this specification.When a user touches an element, the effect of that touch is determined by the value of the touch-action
property and the default touch behaviors on the element and its ancestors. To determine the effect of a touch, find the nearest ancestor (starting from the element itself) that has a default touch behavior. Then examine the touch-action
property of each element between the hit tested element and the element with the default touch behavior (including both the hit tested element and the element with the default touch behavior). If the touch-action
property of any of those elements disallows the default touch behavior, do nothing. Otherwise allow the element to start considering the touch for the purposes of executing a default touch behavior.
During the execution of a behavior, the user agent must not dispatch subsequent pointer events for the pointer. The user agent must dispatch a pointercancel
(and subsequently a pointerout
event) whenever all of the following are true, in order to end the stream of events for the pointer:
pointerdown
event has been sent for the pointer, andpointerup
or pointercancel
event (following the above mentioned pointerdown
) has not yet been sent for the pointer.<div style="touch-action: none;"> This element receives pointer events for all touches. </div>
<div style="touch-action: pan-x;"> This element receives pointer events when not panning in the horizontal direction. </div>
<div style="overflow: auto;"> <div style="touch-action: none;"> This element receives pointer events for all touches. </div> <div> Touches on this element MAY be consumed for manipulating the parent. </div> </div>
<div style="overflow: auto;"> <div style="touch-action: pan-y;"> <div style="touch-action: pan-x;"> This element receives pointer events for all touches because it allows only horizontal panning yet an intermediate ancestor (between it and the pannable element) only allows vertical panning. Therefore, no touch behaviors are allowed. </div> </div> </div>
Pointer capture allows the events for a particular pointer to be retargeted to a particular element other than the normal hit-test result of the pointer's location. This is useful in scenarios like a custom slider control (e.g. similar to the [HTML5] <input type="range">
control). Pointer capture can be set on the slider thumb element, allowing the user to slide the control back and forth even if the pointer slides off of the thumb.
element.setPointerCapture(pointerId)
method. When this method is called, a user agent must run the following steps:
pointerId
provided as the method's argument does not match any of the active pointers, then throw a DOMException
with the name InvalidPointerId
.target
property of all future pointer and compatibility mouse events for the specified pointerId
to the Element
on which this method was invoked.relatedTarget
property of all future pointer and compatibility mouse events for the specified pointerId
to null
.gotpointercapture
event at the Element
on which this method was invoked.element.releasePointerCapture(pointerId)
method. When this method is called, a user agent must run the following steps:
pointerId
provided as the method's argument does not match any of the active pointers, then throw a DOMException
with the name InvalidPointerId
.pointerId
, resume setting the target
property to the hit-test results (out of scope for this specification) for the pointer.lostpointercapture
event at the Element
on which this method was invoked.pointerup
or pointercancel
events, a user agent must run the steps as if the releasePointerCapture()
method has been called with an argument equal to the pointerId
property of the pointerup
orpointercancel
event just dispatched.
The vast majority of web content existing today codes only to Mouse Events. The following describes the algorithm for how a user agent may map generic pointer input to mouse events for compatibility with this content. Unless otherwise noted, the target of any mapped mouse event may be the same as the target for the pointer event from which it was mapped.
Authors can prevent the production of compatibility mouse events by cancelling the pointerdown
event.
The compatibility mapping with mouse events are an optional feature of this specification. User agents are encouraged to support the feature for best compatibility with existing legacy content. User agents that do not support compatibility mouse events are still encouraged to support the click
event (see the note below).
The click
event is defined in [DOM-LEVEL-3-EVENTS] and is not considered a compatibility mouse event as it is typically tied to user interface activation.
In user agents that support firing click
, calling preventDefault
during a pointer event typically does not have an effect on whether click
is fired or not. Because it is not a compatibility mouse event, user agents typically fire click
for all pointing devices, including pointers that are not primary pointers.
isPrimary
property for the pointer event to be dispatched is false
then dispatch the pointer event and terminate these steps.pointerdown
and the event was cancelled, then set the PREVENT MOUSE EVENT flag for this pointerType
.pointerover
, then dispatch a mouseover
event.pointerout
, then dispatch a mouseout
event.pointerenter
, then dispatch a mouseenter
event.pointerleave
, then dispatch a pointerleave
event.pointerType
and the pointer event dispatched was:
pointerdown
, then dispatch a mousedown
event.pointermove
, then dispatch a mousemove
event.pointerup
, then dispatch a mouseup
event.pointercancel
, then dispatch a mouseup
event at the window
.pointerup
or pointercancel
, clear the PREVENT MOUSE EVENT flag for this pointerType
.mouseover
and mouseout
events are never prevented (even if the pointer is down).mousemove
event on an element before clicking itisPrimary
property for the pointer event to be dispatched is false
then dispatch the pointer event and terminate these steps.pointerover
and the pointerdown
event has not yet been dispatched for this pointer, then dispatch a mousemove
event.pointerdown
and the event was cancelled, then set the PREVENT MOUSE EVENT flag for this pointerType
.pointerover
, then dispatch a mouseover
event.pointerout
, then dispatch a mouseout
event.pointerenter
, then dispatch a mouseenter
event.pointerleave
, then dispatch a pointerleave
event.pointerType
and the pointer event dispatched was:
pointerdown
, then dispatch a mousedown
event.pointermove
, then dispatch a mousemove
event.pointerup
, then dispatch a mouseup
event.pointercancel
, then dispatch a mouseup
event at the window
.pointerup
or pointercancel
, clear the PREVENT MOUSE EVENT flag for this pointerType
.mouseover
and mouseout
events are never prevented (even if the pointer is down).This section is non-normative.
The following are example author code that demonstrates how the APIs in this specification might be used.
<style> /* Disable intrinsic user agent touch behaviors (such as panning or zooming) so that all events are given to the application instead. */ html { touch-action: none; } </style> <canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;"></canvas> <script type='text/javascript'> window.addEventListener('load', function() { var canvas = document.getElementById("drawSurface"), context = canvas.getContext("2d"); if (window.navigator.pointerEnabled) { canvas.addEventListener("pointermove", paint, false); if(window.navigator.maxTouchPoints>1) alert("Your user agent and hardware support multi-touch!"); } else { //Provide fallback for user agents that do not support Pointer Events canvas.addEventListener("mousemove", paint, false); } function paint(event) { if(event.buttons>0) context.fillRect(event.clientX, event.clientY, 5, 5); } }); </script>
window.addEventListener("pointerdown", detectInputType, false); function detectInputType(event) { switch(event.pointerType) { case "mouse": alert("You used a mouse!"); break; case "pen": alert("You used a pen stylus!"); break; case "touch": alert("You used touch!"); break; default: alert("Not sure what device was used!"); } }
<div style="position:absolute; top:0px; left:0px; width:100px;height:100px;"></div> <script> window.addEventListener("pointerdown", checkPointerSize, false); function checkPointerSize(event) { event.target.style.width = event.width + "px"; event.target.style.height = event.height + "px"; } </script>
var event = new PointerEvent("pointerover", {bubbles: true, cancelable: true, pointerId: 42, pointerType: "pen", clientX: 300, clientY: 500 }); eventTarget.dispatchEvent(event);
buttons
property. For mouse, this is when the device has at least one button depressed. For touch, this is when there is physical contact with the digitizer. For pen, this is when the pen has physical contact with the digitizer.pointerId
) to produce additional events, then that pointer is still considered active. Examples:
preventDefault()
, returning false
in an event handler, or other means as defined by [DOM-LEVEL-3-EVENTS] and [HTML5].Many thanks to lots of people for their proposals and recommendations, some of which are incorporated into this document.
Special thanks to those that helped pioneer the first edition of this model, including especially: Charu Chandiram, Peter Freiling, Nathan Furtwangler, Thomas Olsen, Matt Rakow, Ramu Ramanathan, Justin Rogers, Jacob Rossi, Reed Townsend, Steve Wright.
This section is non-normative.
The following is an informative summary of substantial and major editorial changes between publications of this specification. A complete revision history of the Editor's Drafts of this specification can be found here.