Copyright © 2021 W3C ® ( MIT , ERCIM , Keio , Beihang ). W3C liability , trademark and permissive document license rules apply.
The features in this specification extend or modify those found in Pointer Events, a W3C Recommendation that describes events and related interfaces for handling hardware agnostic pointer input from devices including a mouse, pen, touchscreen, etc. For compatibility with existing mouse based content, this specification also describes a mapping to fire Mouse Events for other pointer device types.
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 https://www.w3.org/TR/.
This specification is an update to [ PointerEvents2 ] which was shipped broadly by Google Chrome and Microsoft Edge and Mozilla Firefox. Level 3 includes editorial clarifications and new features that facilitate more use cases, in an effort to enable wider developer and browser adoption.
This document was published by the Pointer Events Working Group as an Editor's Draft.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to [email protected] ( subscribe , archives ).
Publication as an Editor's 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 document was produced by a group operating under the 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 .
This document is governed by the 15 September 2020 W3C Process Document .
This section is non-normative.
Today, most [ HTML ] content is used with and/or designed for mouse input. Those that handle input in a custom manner typically code to [ UIEVENTS ] Mouse Events. Newer computing devices today, however, incorporate other forms of input, including touchscreens, pen input, etc. Event types have been proposed for handling each of these forms of input individually. However, that approach often incurs unnecessary duplication of logic and event handling overhead 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 easier 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 easier authoring for cross-device pointer input while still allowing for device-specific handling only when necessary for an augmented experience.
An additional key goal is to enable multi-threaded user agents to handle direct manipulation actions for panning and zooming (for instance, with a finger or stylus on a touchscreen), without blocking on script execution.
While this specification defines a unified event model for a variety of pointer inputs, this model does not cover other forms of input such as keyboards or keyboard-like interfaces (for instance, a screen reader or similar assistive technology running on a touchscreen-only device, which allows users sequential navigation through focusable controls and elements). While user agents might choose to also generate pointer events in response to these interfaces, this scenario is not covered in this specification.
In
the
first
instance,
authors
are
encouraged
to
provide
equivalent
functionality
for
all
forms
of
input
by
responding
to
high-level
events
such
as
focus
,
blur
and
click
.
However,
when
using
low-level
events
(such
as
Pointer
Events),
authors
are
encouraged
to
ensure
that
all
types
of
input
are
supported.
In
the
case
of
keyboards
and
keyboard-like
interfaces,
this
might
require
the
addition
of
explicit
keyboard
event
handling.
See
WCAG
Guideline
2.1
Keyboard
Accessible
[
WCAG21
]
for
further
details.
The
events
for
handling
generic
pointer
input
look
a
lot
like
those
for
mouse:
pointerdown
,
pointermove
,
pointerup
,
pointerover
,
pointerout
,
etc.
This
facilitates
easy
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.
While Pointer Events are sourced from a variety of input devices, they are not defined as being generated from some other set of device-specific events. While possible and encouraged for compatibility, this spec does not require other device-specific events be supported (e.g. mouse events, touch events, etc.). A user agent could support pointer events without supporting any other device events. For compatibility with content written to mouse-specific events, this specification does provide an optional section describing how to generate compatibility mouse events based on pointer input from devices other than a mouse.
This specification does not provide any advice on the expected behavior of user agents that support both Touch Events (as defined in [ TOUCH-EVENTS ]) and Pointer Events. For more information on the relationship between these two specifications, see the Touch Events Community Group .
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 MAY , MUST , MUST NOT , OPTIONAL , SHOULD , and SHOULD NOT in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.
This section is non-normative.
The following are basic examples that demonstrates how some of the APIs in this specification might be used by authors. Further, more specific examples are provided in the relevant sections of this document.
/* Bind to either Pointer Events or traditional touch/mouse */
if (window.PointerEvent) {
// if Pointer Events are supported, only listen to pointer events
target.addEventListener("pointerdown", function(e) {
// if necessary, apply separate logic based on e.pointerType
// for different touch/pen/mouse behavior
...
});
...
} else {
// traditional touch/mouse event handlers
target.addEventListener('touchstart', function(e) {
// prevent compatibility mouse events and click
e.preventDefault();
...
});
...
target.addEventListener('mousedown', ...);
...
}
// additional event listeners for keyboard handling
...
window.addEventListener("pointerdown", detectInputType);
function detectInputType(event) {
switch(event.pointerType) {
case "mouse":
/* mouse input detected */
break;
case "pen":
/* pen/stylus input detected */
break;
case "touch":
/* touch input detected */
break;
default:
/* pointerType is empty (could not be detected)
or UA-specific custom type */
}
}
<div style="position:absolute; top:0px; left:0px; width:100px;height:100px;"></div>
<script>
window.addEventListener("pointerdown", checkPointerSize);
function checkPointerSize(event) {
event.target.style.width = event.width + "px";
event.target.style.height = event.height + "px";
}
</
script
>
const event1 = new PointerEvent("pointerover",
{ bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500
});
eventTarget.dispatchEvent(event1);
let pointerEventInitDict =
{
bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500,
};
const p1 = new PointerEvent("pointermove", pointerEventInitDict);
pointerEventInitDict.clientX += 10;
const p2 = new PointerEvent("pointermove", pointerEventInitDict);
pointerEventInitDict.coalescedEvents = [p1, p2];
const event2 = new PointerEvent("pointermove", pointerEventInitDict);
eventTarget.dispatchEvent(event2);
PointerEvent
Interface
WebIDLdictionary PointerEventInit : MouseEventInit {
long pointerId = 0;
double width = 1;
double height = 1;
float pressure = 0;
float tangentialPressure = 0;
long tiltX;
long tiltY;
long twist = 0;
double altitudeAngle;
double azimuthAngle;
DOMString pointerType = "";
boolean isPrimary = false;
sequence<PointerEvent> coalescedEvents = [];
sequence<PointerEvent> predictedEvents = [];
};
[Exposed=Window]
interface PointerEvent : MouseEvent {
constructor(DOMString type, optional PointerEventInit eventInitDict = {});
readonly attribute long pointerId;
readonly attribute double width;
readonly attribute double height;
readonly attribute float pressure;
readonly attribute float tangentialPressure;
readonly attribute long tiltX;
readonly attribute long tiltY;
readonly attribute long twist;
readonly attribute double altitudeAngle;
readonly attribute double azimuthAngle;
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
[SecureContext] sequence<PointerEvent> getCoalescedEvents();
sequence<PointerEvent> getPredictedEvents();
};
pointerId
A
unique
identifier
for
the
pointer
causing
the
event.
This
identifier
MUST
be
unique
from
all
other
active
pointers
in
the
top-level
browsing
context
(as
defined
by
[
HTML
])
at
the
time.
The
pointerId
value
of
-1
is
reserved
to
indicate
events
that
were
generated
by
something
other
than
a
pointing
device.
A
user
agent
MAY
recycle
previously
retired
values
for
pointerId
from
previous
active
pointers,
if
necessary.
The
pointerId
selection
algorithm
is
implementation
specific.
Therefore
authors
cannot
assume
values
convey
any
particular
meaning
other
than
an
identifier
for
the
pointer
that
is
unique
from
all
other
active
pointers.
As
an
example,
user
agents
may
simply
assign
a
number,
starting
from
1
,
to
any
active
pointers,
in
the
order
that
they
become
active
-
but
these
values
are
not
guaranteed
to
be
monotonically
increasing.
Other
user
agents
may
opt
to
assign
a
completely
randomized
and
unique
number
to
each
active
pointer.
However,
in
the
latter
scenarios
user
agents
MUST
ensure
that
the
pointerId
that
is
assigned
remains
the
same
only
for
the
lifetime
of
the
current
page,
and
that
any
new
pointerId
values
are
not
predictable
(e.g.
generated
randomly
with
cryptographically
strong
randomness),
to
minimize
the
possibility
of
users
being
uniquely
fingerprinted
and
tracked
across
different
pages.
width
The width (magnitude on the X axis), in CSS pixels (see [ CSS21 ]), of the contact geometry of the pointer. This value MAY be updated on each event for a given pointer. For inputs that typically lack contact geometry (such as a traditional mouse), and in cases where the actual geometry of the input is not detected by the hardware, the user agent MUST return a default value of 1.
height
The height (magnitude on the Y axis), in CSS pixels (see [ CSS21 ]), of the contact geometry of the pointer. This value MAY be updated on each event for a given pointer. For inputs that typically lack contact geometry (such as a traditional mouse), and in cases where the actual geometry of the input is not detected by the hardware, the user agent MUST return a default value of 1.
pressure
The
normalized
pressure
of
the
pointer
input
in
the
range
of
[0,1],
where
0
and
1
represent
the
minimum
and
maximum
pressure
the
hardware
is
capable
of
detecting,
respectively.
For
hardware
and
platforms
that
do
not
support
pressure,
the
value
MUST
be
0.5
when
in
the
active
buttons
state
and
0
otherwise.
Note:
all
pointerup
events
will
have
pressure
0.
tangentialPressure
The normalized tangential pressure (also known as barrel pressure), typically set by an additional control (e.g. a finger wheel on an airbrush stylus), of the pointer input in the range of [-1,1], where 0 is the neutral position of the control. Note that some hardware may only support positive values in the range of [0,1]. For hardware and platforms that do not support tangential pressure, the value MUST be 0.
tiltX
The
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
hardware
and
platforms
that
do
not
report
tilt
or
angle,
the
value
MUST
be
0.
tiltX
.
tiltY
The
plane
angle
(in
degrees,
in
the
range
of
[-90,90])
between
the
X-Z
plane
and
the
plane
containing
both
the
transducer
(e.g.
pen/stylus)
axis
and
the
X
axis.
A
positive
tiltY
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
hardware
and
platforms
that
do
not
report
tilt
or
angle,
the
value
MUST
be
0.
tiltY
.
twist
The clockwise rotation (in degrees, in the range of [0,359]) of a transducer (e.g. pen/stylus) around its own major axis. For hardware and platforms that do not report twist, the value MUST be 0.
altitudeAngle
The altitude (in radians) of the transducer (e.g. pen/stylus), in the range [0,π/2] - where 0 is parallel to the surface (X-Y plane), and π/2 is perpendicular to the surface. For hardware and platforms that do not report tilt or angle, the value MUST be π/2.
altitudeAngle
in
Touch
Events
-
Level
2
specification,
the
default
value
defined
here
is
π/2.
This
correlates
with
the
default
values
of
0
for
both
tiltX
and
tiltY
(when
the
hardware
or
platform
do
not
report
them)
which
positions
the
transducer
as
being
perpendicular
to
the
surface.
altitudeAngle
of
π/4
(45
degrees
from
the
X-Y
plane).
azimuthAngle
The
azimuth
angle
(in
radians)
of
the
transducer
(e.g.
pen/stylus),
in
the
range
[0,
2π]
-
where
0
represents
a
transducer
whose
cap
is
pointing
in
the
direction
of
increasing
X
values
(point
to
"3
o'clock"
if
looking
straight
down)
on
the
X-Y
plane,
and
the
values
progressively
increase
when
going
clockwise
(π/2
at
"6
o'clock",
π
at
"9
o'clock",
3π/2
at
"12
o'clock").
When
the
transducer
is
perfectly
perpendicular
to
the
surface
(
altitudeAngle
of
π/2),
the
value
MUST
be
0.
For
hardware
and
platforms
that
do
not
report
tilt
or
angle,
the
value
MUST
be
0.
azimuthAngle
of
π/6
("4
o'clock").
pointerType
Indicates
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.
pointerType
can
be
used.
Also
note
that
developers
should
include
some
form
of
default
handling
to
cover
user
agents
that
may
have
implemented
their
own
custom
pointerType
values
and
for
situations
where
pointerType
is
simply
an
empty
string.
isPrimary
Indicates if the pointer represents the primary pointer of this pointer type.
getCoalescedEvents()
method
A method that returns the list of coalesced events .
getPredictedEvents()
method
A method that returns the list of predicted events .
The
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
[
UIEVENTS
].
The
event
constructing
steps
are
defined
in
the
DOM
Standard
.
See
the
examples
for
sample
code
demonstrating
how
to
fire
an
untrusted
pointer
event.
Pointer
Events
include
two
complementary
sets
of
attributes
to
express
the
orientation
of
a
transducer
relative
to
the
X-Y
plane:
tiltX
/
tiltY
(introduced
in
the
original
Pointer
Events
specification),
and
azimuthAngle
/
altitudeAngle
(adopted
from
the
Touch
Events
-
Level
2
specification).
Implementations
SHOULD
provide
both
sets
of
attributes
for
trusted
events.
When an untrusted (synthetic) Pointer Event is created programmatically using the constructor, and only one set of attributes is provided, the complementary set of attributes SHOULD be calculated and initialized by the user agent. If both sets of attributes are provided, no calculation should be performed. If only the value of one of the two attributes is provided, the other attribute SHOULD be initialized to the default value.
When
the
user
agent
calculates
tiltX
/
tiltY
from
azimuthAngle
/
altitudeAngle
it
SHOULD
round
the
final
integer
values
using
Math.round
[
ECMASCRIPT
]
rules.
PointerEvent
interface
inherits
from
MouseEvent
,
defined
in
UI
Events
and
extended
by
CSSOM
View
Module
.
In
a
multi-pointer
(e.g.
multi-touch)
scenario,
the
isPrimary
property
is
used
to
identify
a
master
pointer
amongst
the
set
of
active
pointers
for
each
pointer
type.
pointerType
)
are
considered
primary.
For
example,
a
touch
contact
and
a
mouse
cursor
moved
simultaneously
will
produce
pointers
that
are
both
considered
primary.
false
for
isPrimary
.
PointerEvent
interface
To
fire
a
pointer
event
named
e
means
to
fire
an
event
named
e
using
PointerEvent
whose
attributes
are
set
as
defined
in
PointerEvent
Interface
and
Attributes
and
Default
Actions
.
If
the
event
is
not
gotpointercapture
or
lostpointercapture
,
run
Process
Pending
Pointer
Capture
steps
for
this
PointerEvent
.
The target object at which the event is fired is determined as follows:
Let targetDocument be target's node document [ DOM ].
If
the
event
is
pointerdown
,
pointermove
,
or
pointerup
set
active
document
for
the
event's
pointerId
to
targetDocument
.
If
the
event
is
pointerdown
,
the
associated
device
is
a
direct
manipulation
device,
and
the
target
is
an
Element
,
then
set
pointer
capture
for
this
pointerId
to
the
target
element
as
described
in
implicit
pointer
capture
.
Fire the event to the determined target.
The
bubbles
and
cancelable
properties
and
the
default
actions
for
the
event
types
defined
in
this
specification
appear
in
the
following
table.
Details
of
each
of
these
event
types
are
provided
in
Pointer
Event
types
.
| Event Type | Bubbles | Cancelable | Default Action |
|---|---|---|---|
pointerover
|
Yes | Yes | None |
pointerenter
|
No | No | None |
pointerdown
|
Yes | Yes |
Varies:
when
the
pointer
is
primary,
all
default
actions
of
the
mousedown
event
Canceling this event also sets the
PREVENT
MOUSE
EVENT
flag
for
this
pointerType
,
which
prevents
subsequent
firing
of
certain
compatibility
mouse
events
.
|
pointermove
|
Yes | Yes |
Varies:
when
the
pointer
is
primary,
all
default
actions
of
mousemove
|
pointerup
|
Yes | Yes |
Varies:
when
the
pointer
is
primary,
all
default
actions
of
mouseup
|
pointercancel
|
Yes | No | None |
pointerout
|
Yes | Yes | None |
pointerleave
|
No | No | None |
gotpointercapture
|
Yes | No | None |
lostpointercapture
|
Yes | No | None |
Viewport
manipulations
(panning
and
zooming)
-
generally,
as
a
result
of
a
direct
manipulation
interaction
-
are
intentionally
NOT
a
default
action
of
pointer
events,
meaning
that
these
behaviors
(e.g.
panning
a
page
as
a
result
of
moving
a
finger
on
a
touchscreen)
cannot
be
suppressed
by
cancelling
a
pointer
event.
Authors
must
instead
use
touch-action
to
explicitly
declare
the
direct
manipulation
behavior
for
a
region
of
the
document.
Removing
this
dependency
on
the
cancellation
of
events
facilitates
performance
optimizations
by
the
user
agent.
For
all
pointer
events
in
the
table
above
except
pointerenter
and
pointerleave
the
composed
[
DOM
]
attribute
SHOULD
be
true
.
For
all
pointer
events
in
the
table
above
the
detail
[
UIEVENTS
]
attribute
SHOULD
be
0.
fromElement
and
toElement
in
MouseEvents
to
support
legacy
content.
In
those
user
agents,
the
values
of
those
(inherited)
attributes
in
PointerEvents
must
be
null
to
encourage
the
use
of
the
standardized
alternates
(i.e.
target
and
relatedTarget
).
Similar
to
MouseEvent
relatedTarget
,
the
relatedTarget
should
be
initialized
to
the
element
whose
bounds
the
pointer
just
left
(in
the
case
of
a
pointerover
or
pointerenter
event)
or
the
element
whose
bounds
the
pointer
is
entering
(in
the
case
of
a
pointerout
or
pointerleave
).
For
other
pointer
events,
this
value
will
default
to
null.
Note
that
when
an
element
receives
the
pointer
capture
all
the
following
events
for
that
pointer
are
considered
to
be
inside
the
boundary
of
the
capturing
element.
For
gotpointercapture
and
lostpointercapture
all
the
attributes
except
the
ones
defined
in
the
table
above
should
be
the
same
as
the
Pointer
Event
that
caused
the
user
agent
to
run
Process
Pending
Pointer
Capture
and
fire
the
gotpointercapture
and
lostpointercapture
events.
The
user
agent
MUST
run
the
following
steps
when
implicitly
releasing
pointer
capture
as
well
as
when
firing
Pointer
Events
that
are
not
gotpointercapture
or
lostpointercapture
.
lostpointercapture
at
the
pointer
capture
target
override
node.
gotpointercapture
at
the
pending
pointer
capture
target
override
.
Below are the event types defined in this specification.
In
the
case
of
the
primary
pointer
,
these
events
(with
the
exception
of
gotpointercapture
and
lostpointercapture
)
may
also
fire
compatibility
mouse
events
.
pointerover
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerover
when
a
pointing
device
is
moved
into
the
hit
test
boundaries
of
an
element.
Note
that
setPointerCapture
or
releasePointerCapture
might
have
changed
the
hit
test
target
and
while
a
pointer
is
captured
it
is
considered
to
be
always
inside
the
boundaries
of
the
capturing
element
for
the
purpose
of
firing
boundary
events.
A
user
agent
MUST
also
fire
this
event
prior
to
firing
a
pointerdown
event
for
devices
that
do
not
support
hover
(see
pointerdown
).
pointerenter
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerenter
when
a
pointing
device
is
moved
into
the
hit
test
boundaries
of
an
element
or
one
of
its
descendants,
including
as
a
result
of
a
pointerdown
event
from
a
device
that
does
not
support
hover
(see
pointerdown
).
Note
that
setPointerCapture
or
releasePointerCapture
might
have
changed
the
hit
test
target
and
while
a
pointer
is
captured
it
is
considered
to
be
always
inside
the
boundaries
of
the
capturing
element
for
the
purpose
of
firing
boundary
events.
This
event
type
is
similar
to
pointerover
,
but
differs
in
that
it
does
not
bubble.
mouseenter
event
described
in
[
UIEVENTS
],
and
the
CSS
:hover
pseudo-class
described
in
[
CSS21
].
See
also
the
pointerleave
event
.
pointerdown
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerdown
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
pen
either
makes
physical
contact
with
the
digitizer
without
any
button
depressed,
or
transitions
from
no
buttons
depressed
to
at
least
one
button
depressed
while
hovering.
pointerdown
and
pointerup
are
not
fired
for
all
of
the
same
circumstances
as
mousedown
and
mouseup
.
See
chorded
buttons
for
more
information.
For
input
devices
that
do
not
support
hover
,
a
user
agent
MUST
also
fire
a
pointer
event
named
pointerover
followed
by
a
pointer
event
named
pointerenter
prior
to
dispatching
the
pointerdown
event.
pointerdown
event
(if
the
isPrimary
property
is
true
).
This
sets
the
PREVENT
MOUSE
EVENT
flag
on
the
pointer.
Note,
however,
that
this
does
not
prevent
the
mouseover
,
mouseenter
,
mouseout
,
or
mouseleave
events
from
firing.
pointermove
event
A
user
agent
MUST
fire
a
pointer
event
named
pointermove
when
a
pointer
changes
button
state.
Additionally
one
pointermove
MUST
be
fired
when
pointer
changes
coordinates,
pressure,
tangential
pressure,
tilt,
twist,
or
contact
geometry
(e.g.
width
and
height
)
and
the
circumstances
produce
no
other
pointer
events
defined
in
this
specification.
User
agents
MAY
delay
dispatch
of
the
pointermove
event
(for
instance,
for
performance
reasons).
The
coalesced
events
information
will
be
exposed
via
for
the
single
dispatched
getCoalescedEvents
pointermove
event.
The
final
coordinates
of
such
events
should
be
used
for
finding
the
target
of
the
event.
pointerrawupdate
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerrawupdate
only
within
a
secure
context
when
a
pointing
device
attribute
pointer's
attributes
(i.e.
button
state,
coordinates,
pressure,
tangential
pressure,
tilt,
twist,
or
contact
geometry)
is
changed.
change.
In
contrast
with
pointermove
,
user
agents
SHOULD
dispatch
pointerrawupdate
events
as
soon
as
possible
and
as
frequently
as
the
JavaScript
can
handle
the
events.
The
target
of
pointerrawupdate
events
might
be
different
from
the
pointermove
events
due
to
the
fact
that
pointermove
events
might
get
delayed
or
coalesced,
and
the
final
position
of
the
event
which
is
used
for
finding
the
target
could
be
different
from
its
coalesced
events.
Note
that
if
there
is
already
another
pointerrawupdate
with
the
same
pointerId
that
hasn't
been
dispatched
in
the
event
loop
,
the
user
agent
MAY
coalesce
the
new
pointerrawupdate
with
that
event
instead
of
creating
a
new
task
.
This
may
cause
pointerrawupdate
to
have
coalesced
events,
and
they
will
all
be
delivered
as
coalesced
events
of
one
pointerrawupdate
event
as
soon
as
the
event
is
processed
in
the
event
loop
.
See
for
more
information.
getCoalescedEvents
In
terms
of
ordering
of
pointerrawupdate
and
pointermove
,
if
the
user
agent
received
an
update
from
the
platform
that
causes
both
pointerrawupdate
and
pointermove
events,
then
the
user
agent
MUST
dispatch
the
pointerrawupdate
event
before
the
corresponding
pointermove
.
Other
than
the
target
,
the
concatenation
of
coalesced
events
lists
of
all
dispatched
pointerrawupdate
events
since
the
last
pointermove
event
is
the
same
as
the
coalesced
events
of
the
next
pointermove
event
in
terms
of
the
other
event
attributes.
The
attributes
of
pointerrawupdate
are
mostly
the
same
as
pointermove
,
with
the
exception
of
cancelable
which
MUST
be
false
for
pointerrawupdate
.
User
agents
SHOULD
not
fire
compatibility
mouse
events
for
pointerrawupdate
.
pointerrawupdate
event
might
negatively
impact
the
performance
of
the
web
page,
depending
on
the
implementation
of
the
user
agent.
For
most
use
cases
the
other
pointerevent
types
should
suffice.
A
pointerrawupdate
listener
should
only
be
added
if
JavaScript
needs
high
frequency
events
and
can
handle
them
just
as
fast.
In
these
cases,
there
is
probably
no
need
to
listen
to
other
types
of
pointer
events.
pointerup
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerup
when
a
pointer
leaves
the
active
buttons
state
.
For
mouse,
this
is
when
the
device
transitions
from
at
least
one
button
depressed
to
no
buttons
depressed.
For
touch,
this
is
when
physical
contact
is
removed
from
the
digitizer
.
For
pen,
this
is
when
the
pen
is
removed
from
the
physical
contact
with
the
digitizer
while
no
button
is
depressed,
or
transitions
from
at
least
one
button
depressed
to
no
buttons
depressed
while
hovering.
For
input
devices
that
do
not
support
hover
,
a
user
agent
MUST
also
fire
a
pointer
event
named
pointerout
followed
by
a
pointer
event
named
pointerleave
after
dispatching
the
pointerup
event.
pointerdown
and
pointerup
are
not
fired
for
all
of
the
same
circumstances
as
mousedown
and
mouseup
.
See
chorded
buttons
for
more
information.
pointercancel
event
A
user
agent
MUST
fire
a
pointer
event
named
pointercancel
in
the
following
circumstances:
pointerdown
event,
if
the
pointer
is
subsequently
used
to
manipulate
the
page
viewport
(e.g.
panning
or
zooming).
preventDefault
on
the
dragstart
event)
there
will
be
no
pointercancel
event.
After
firing
the
pointercancel
event,
a
user
agent
MUST
also
fire
a
pointer
event
named
pointerout
followed
by
firing
a
pointer
event
named
pointerleave
.
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.
pointerout
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerout
when
any
of
the
following
occurs:
setPointerCapture
or
releasePointerCapture
might
have
changed
the
hit
test
target
and
while
a
pointer
is
captured
it
is
considered
to
be
always
inside
the
boundaries
of
the
capturing
element
for
the
purpose
of
firing
boundary
events.
pointerup
event
for
a
device
that
does
not
support
hover
(see
pointerup
).
pointercancel
event
(see
pointercancel
).
pointerleave
event
A
user
agent
MUST
fire
a
pointer
event
named
pointerleave
when
a
pointing
device
is
moved
out
of
the
hit
test
boundaries
of
an
element
and
all
of
its
descendants,
including
as
a
result
of
a
pointerup
and
pointercancel
events
from
a
device
that
does
not
support
hover
(see
pointerup
and
pointercancel
).
Note
that
setPointerCapture
or
releasePointerCapture
might
have
changed
the
hit
test
target
and
while
a
pointer
is
captured
it
is
considered
to
be
always
inside
the
boundaries
of
the
capturing
element
for
the
purpose
of
firing
boundary
events.
User
agents
MUST
also
fire
a
pointer
event
named
pointerleave
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
fired
until
the
pointing
device
has
left
the
boundaries
of
the
element
and
the
boundaries
of
all
of
its
descendants.
gotpointercapture
event
A
user
agent
MUST
fire
a
pointer
event
named
gotpointercapture
when
an
element
receives
pointer
capture.
This
event
is
fired
at
the
element
that
is
receiving
pointer
capture.
Subsequent
events
for
that
pointer
will
be
fired
at
this
element.
See
the
Setting
Pointer
Capture
and
Process
Pending
Pointer
Capture
sections.
lostpointercapture
event
A
user
agent
MUST
fire
a
pointer
event
named
lostpointercapture
after
pointer
capture
is
released
for
a
pointer.
This
event
MUST
be
fired
prior
to
any
subsequent
events
for
the
pointer
after
capture
was
released.
This
event
is
fired
at
the
element
from
which
pointer
capture
was
removed.
Subsequent
events
for
the
pointer
follow
normal
hit
testing
mechanisms
(out
of
scope
for
this
specification)
for
determining
the
event
target.
See
the
Releasing
Pointer
Capture
,
Implicit
Release
of
Pointer
Capture
,
and
Process
Pending
Pointer
Capture
sections.
Element
interface
The
following
section
describes
extensions
to
the
existing
Element
interface
to
facilitate
the
setting
and
releasing
of
pointer
capture.
WebIDLpartial interface Element {
undefined setPointerCapture (long pointerId);
undefined releasePointerCapture (long pointerId);
boolean hasPointerCapture (long pointerId);
};
setPointerCapture
Sets
pointer
capture
for
the
pointer
identified
by
the
argument
pointerId
to
the
element
on
which
this
method
is
invoked.
For
subsequent
events
of
the
pointer,
the
capturing
target
will
substitute
the
normal
hit
testing
result
as
if
the
pointer
is
always
over
the
capturing
target,
and
they
MUST
always
be
targeted
at
this
element
until
capture
is
released.
The
pointer
MUST
be
in
its
active
buttons
state
for
this
method
to
be
effective,
otherwise
it
fails
silently.
When
the
provided
method's
argument
does
not
match
any
of
the
active
pointers
,
throw
a
"
NotFoundError
"
DOMException
.
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.
When
the
provided
method's
argument
does
not
match
any
of
the
active
pointers
,
throw
a
"
NotFoundError
"
DOMException
.
hasPointerCapture
Indicates
whether
the
element
on
which
this
method
is
invoked
has
pointer
capture
for
the
pointer
identified
by
the
argument
pointerId
.
In
particular,
returns
true
if
the
pending
pointer
capture
target
override
for
pointerId
is
set
to
the
element
on
which
this
method
is
invoked,
and
false
otherwise.
setPointerCapture
,
even
though
that
element
will
not
yet
have
received
a
gotpointercapture
event
.
As
a
result
it
can
be
useful
for
detecting
implicit
pointer
capture
from
inside
of
a
pointerdown
event
listener.
GlobalEventHandlers
mixin
The
following
section
describes
extensions
to
the
existing
GlobalEventHandlers
mixin
to
facilitate
the
event
handler
registration.
WebIDLpartial interface mixin GlobalEventHandlers {
attribute EventHandler ongotpointercapture;
attribute EventHandler onlostpointercapture;
attribute EventHandler onpointerdown;
attribute EventHandler onpointermove;
[SecureContext] attribute EventHandler onpointerrawupdate;
attribute EventHandler onpointerup;
attribute EventHandler onpointercancel;
attribute EventHandler onpointerover;
attribute EventHandler onpointerout;
attribute EventHandler onpointerenter;
attribute EventHandler onpointerleave;
};
ongotpointercapture
gotpointercapture
event
type.
onlostpointercapture
lostpointercapture
event
type.
onpointerdown
pointerdown
event
type.
onpointermove
pointermove
event
type.
onpointerup
pointerup
event
type.
onpointercancel
pointercancel
event
type.
onpointerover
pointerover
event
type.
onpointerout
pointerout
event
type.
onpointerenter
pointerenter
event
type.
onpointerleave
pointerleave
event
type.
As
noted
in
Attributes
and
Default
Actions
,
viewport
manipulations
(panning
and
zooming)
cannot
be
suppressed
by
cancelling
a
pointer
event.
Instead,
authors
must
explicitly
define
which
of
these
behaviors
they
want
to
allow,
and
which
they
want
to
suppress,
using
the
touch-action
CSS
property.
touch-action
CSS
property
defined
in
this
specification
appears
to
refer
only
to
touch
inputs,
it
does
in
fact
apply
to
all
forms
of
pointer
inputs
that
allow
direct
manipulation
for
panning
and
zooming.
touch-action
CSS
property
| Name: |
touch-action
|
|---|---|
| Value: |
auto
|
none
|
[
[
pan-x
|
pan-left
|
pan-right
]
||
[
pan-y
|
pan-up
|
pan-down
]
]
|
manipulation
|
| Initial: |
auto
|
| Applies to: | all elements except: non-replaced inline elements, table rows, row groups, table columns, and column groups. |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | Same as specified value. |
The
touch-action
CSS
property
determines
whether
direct
manipulation
interactions
(which
are
not
limited
to
touch,
despite
the
property's
name)
MAY
trigger
the
user
agent's
panning
and
zooming
behavior.
See
the
section
on
touch-action
values
.
While
panning
and
zooming,
the
user
agent
MUST
NOT
fire
subsequent
pointer
events
for
the
pointer.
In
order
to
end
the
stream
of
events
for
the
pointer,
the
user
agent
MUST
fire
a
pointer
event
named
pointercancel
(and
subsequently
a
pointerout
event
and
one
or
more
pointerleave
events)
whenever
all
of
the
following
are
true:
pointerdown
event
has
been
sent
for
the
pointer,
and
pointerup
or
pointercancel
event
(following
the
above
mentioned
pointerdown
)
has
not
yet
been
sent
for
the
pointer.
touch-action
does
not
apply/cascade
through
to
embedded
browsing
contexts.
For
instance,
even
applying
touch-action
to
an
<iframe>
won't
have
any
effect
on
the
behavior
of
direct
manipulation
interactions
for
panning
and
zooming
within
the
<iframe>
itself.
When
a
user
interacts
with
an
element
using
a
direct
manipulation
pointer
(such
as
touch
or
stylus
on
a
touchscreen),
the
effect
of
that
input
is
determined
by
the
value
of
the
touch-action
property,
and
the
default
direct
manipulation
behaviors
of
the
element
and
its
ancestors,
as
follows:
touch-action
if
the
behavior
is
allowed
in
the
coordinate
space
of
the
element.
Note
that
if
CSS
transforms
have
been
applied,
the
element's
coordinate
space
may
differ
from
the
screen
coordinate
in
a
way
to
affect
the
conformity
here;
for
example,
the
X
axis
of
an
element
rotated
by
90
degrees
with
respect
to
the
screen
will
be
parallel
to
the
Y-axis
of
the
screen
coordinate.
touch-action
property
of
each
element
between
the
hit
tested
element
and
its
nearest
ancestor
with
the
default
direct
manipulation
behavior
(including
both
the
hit
tested
element
and
the
element
with
the
default
direct
manipulation
behavior).
touch-action
value
will
be
ignored
for
the
duration
of
the
action.
For
instance,
programmatically
changing
the
touch-action
value
for
an
element
from
auto
to
none
as
part
of
a
pointerdown
handler
script
will
not
result
in
the
user
agent
aborting
or
suppressing
any
of
the
pan
or
zoom
behavior
for
that
input
for
as
long
as
that
pointer
is
active.
touch-action
values
of
pan-*
,
once
the
user
agent
has
determined
whether
to
handle
a
gesture
directly
or
not
at
the
start
of
the
gesture,
a
subsequent
change
in
the
direction
of
the
same
gesture
SHOULD
be
ignored
by
the
user
agent
for
as
long
as
that
pointer
is
active.
For
instance,
if
an
element
has
been
set
to
touch-action:
pan-y
(meaning
that
only
vertical
panning
is
handled
by
the
user
agent),
and
a
touch
gesture
starts
off
horizontally,
no
vertical
panning
should
occur
if
the
user
changes
the
direction
of
their
gesture
to
be
vertical
while
their
finger
is
still
touching
the
screen.
touch-action
values
of
multiple
concurrent
pointers
is
out
of
scope
for
this
specification.
touch-action
values
The
touch-action
property
covers
direct
manipulation
behaviors
related
to
viewport
panning
and
zooming.
Any
additional
user
agent
behaviors,
such
as
text
selection/highlighting,
or
activating
links
and
form
controls,
MUST
NOT
be
affected
by
this
CSS
property.
auto
or
none
values,
are
out
of
scope
for
this
specification.
pan-y
),
the
axis
cannot
be
changed
during
panning.
touch-action
values
common
in
implementations
are
defined
in
[
COMPAT
].
touch-action
property
only
applies
to
elements
that
support
both
the
CSS
width
and
height
properties
(see
[
CSS21
]).
This
restriction
is
designed
to
facilitate
user
agent
optimizations
for
low-latency
direct
manipulation
panning
and
zooming.
For
elements
not
supported
by
default,
such
as
<span>
which
is
a
non-replaced
inline
element
,
authors
can
set
the
display
CSS
property
to
a
value,
such
as
block
,
that
supports
width
and
height
.
Future
specifications
could
extend
this
API
to
all
elements.
The
direction-specific
pan
values
are
useful
for
customizing
some
overscroll
behaviors.
For
example,
to
implement
a
simple
pull-to-refresh
effect
the
document's
touch-action
can
be
set
to
pan-x
pan-down
whenever
the
scroll
position
is
0
and
pan-x
pan-y
otherwise.
This
allows
pointer
event
handlers
to
define
the
behavior
for
upward
panning/scrolling
that
start
from
the
top
of
the
document.
The
direction-specific
pan
values
can
also
be
used
for
composing
a
component
that
implements
custom
panning
with
pointer
event
handling
within
an
element
that
scrolls
natively
(or
vice-versa).
For
example,
an
image
carousel
may
use
pan-y
to
ensure
it
receives
pointer
events
for
any
horizontal
pan
operations
without
interfering
with
vertical
panning
of
the
document.
When
the
carousel
reaches
its
right-most
extent,
it
may
change
its
touch-action
to
pan-y
pan-right
so
that
a
subsequent
scroll
operation
beyond
its
extent
can
scroll
the
document
within
the
viewport
if
possible.
It's
not
possible
to
change
the
behavior
of
a
panning/scrolling
operation
while
it
is
taking
place.
auto
user
agents
typically
add
300ms
of
delay
before
click
to
allow
for
double-tap
gestures
to
be
handled.
In
these
cases,
explicitly
setting
touch-action:
none
or
touch-action:
manipulation
will
remove
this
delay.
Note
that
the
methods
for
determining
a
tap
or
double-tap
gesture
are
out
of
scope
for
this
specification.
<div style="touch-action: none;">
This element receives pointer events for all direct manipulation interactions that otherwise lead to panning or zooming.
</
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 direct manipulation interactions that otherwise lead to panning or zooming.
</div>
<div>
Direct manipulation interactions 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 direct manipulation interactions because
it allows only horizontal panning yet an intermediate ancestor
(between it and the scrollable element) only allows vertical panning.
Therefore, no direct manipulation behaviors for panning/zooming are
handled by the user agent.
</div>
</div>
</
div
>
<div style="overflow: auto;">
<div style="touch-action: pan-y pan-left;">
<div style="touch-action: pan-x;">
This element receives pointer events when not panning to the left.
</div>
</div>
</
div
>
This section is non-normative.
Pointer
capture
allows
the
events
for
a
particular
pointer
(including
any
compatibility
mouse
events
)
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
[
HTML
]
<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.
pointerdown
on
the
thumb,
pointer
capture
can
be
used
to
allow
the
user
to
slide
the
thumb
even
if
the
pointer
drifts
off
of
it.
Pointer
capture
is
set
on
an
element
of
type
Element
by
calling
the
element.setPointerCapture(pointerId)
method.
When
this
method
is
invoked,
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
"
NotFoundError
"
DOMException
.
pointerId
.
InvalidStateError
"
DOMException
.
pointerLockElement
),
throw
an
"
InvalidStateError
"
DOMException
.
pointerId
,
set
the
pending
pointer
capture
target
override
to
the
Element
on
which
this
method
was
invoked.
Pointer
capture
is
released
on
an
element
explicitly
by
calling
the
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
and
these
steps
are
not
being
invoked
as
a
result
of
the
implicit
release
of
pointer
capture
,
then
throw
a
"
NotFoundError
"
DOMException
.
Element
with
the
specified
pointerId
,
then
terminate
these
steps.
pointerId
,
clear
the
pending
pointer
capture
target
override
,
if
set.
Inputs
that
implement
direct
manipulation
interactions
for
panning
and
zooming
(such
as
touch
or
stylus
on
a
touchscreen)
SHOULD
behave
exactly
as
if
setPointerCapture
was
called
on
the
target
element
just
before
the
invocation
of
any
pointerdown
listeners.
The
hasPointerCapture
API
may
be
used
(eg.
within
any
pointerdown
listener)
to
determine
whether
this
has
occurred.
If
releasePointerCapture
is
not
called
for
the
pointer
before
the
next
pointer
event
is
fired,
then
a
gotpointercapture
event
will
be
dispatched
to
the
target
(as
normal)
indicating
that
capture
is
active.
Immediately
after
firing
the
pointerup
or
pointercancel
events,
a
user
agent
MUST
clear
the
pending
pointer
capture
target
override
for
the
pointerId
of
the
pointerup
or
pointercancel
event
that
was
just
dispatched,
and
then
run
Process
Pending
Pointer
Capture
steps
to
fire
lostpointercapture
if
necessary.
After
running
Process
Pending
Pointer
Capture
steps,
if
the
pointer
supports
hover,
user
agent
MUST
also
send
corresponding
boundary
events
necessary
to
reflect
the
current
position
of
the
pointer
with
no
capture.
If
the
user
agent
supports
firing
the
click
event
(see
compatibility
mouse
events
),
and
if
in
an
implicit
release
scenario
both
click
and
lostpointercapture
events
are
fired,
click
SHOULD
be
fired
before
lostpointercapture
.
When
the
pointer
capture
target
override
is
no
longer
connected
[
DOM
],
the
pending
pointer
capture
target
override
and
pointer
capture
target
override
nodes
SHOULD
be
cleared
and
also
a
PointerEvent
named
lostpointercapture
corresponding
to
the
captured
pointer
SHOULD
be
fired
at
the
document.
When
a
pointer
lock
[
PointerLock
]
is
successfully
applied
on
an
element,
a
user
agent
MUST
run
the
steps
as
if
the
releasePointerCapture()
method
has
been
called
if
any
element
is
set
to
be
captured
or
pending
to
be
captured.
For
performance
reasons,
user
agents
may
choose
not
to
send
a
pointermove
event
every
time
the
position
a
measurable
property
(such
as
coordinates,
pressure,
tangential
pressure,
tilt,
twist,
or
contact
geometry)
of
a
pointer
is
updated.
Instead,
they
will
may
coalesce
(combine/merge)
multiple
position
changes
into
a
single
move
pointermove
or
pointerrawupdate
event.
While
this
approach
helps
in
reducing
the
amount
of
event
handling
the
user
agent
must
perform,
it
will
naturally
reduce
the
granularity
and
fidelity
when
tracking
a
pointer
position,
particularly
for
fast
and
large
movements.
Using
the
method
it
is
possible
for
applications
to
access
the
raw,
un-coalesced
position
changes.
These
allow
for
a
more
precise
handling
of
pointer
movement
data.
In
the
case
of
drawing
applications,
for
instance,
the
un-coalesced
events
can
be
used
to
draw
smoother
curves
that
more
closely
match
the
actual
movement
of
a
pointer.
getCoalescedEvents
pointermove
events
(the
grey
dots),
the
curve
is
noticeably
angular
and
jagged;
the
same
line
drawn
using
the
more
granular
points
provided
by
getCoalescedEvents
(the
red
circles)
results
in
a
smoother
approximation
of
the
pointer
movement.
A
PointerEvent
has
an
associated
coalesced
event
list
(a
list
of
zero
or
more
PointerEvent
s).
If
this
event
is
a
pointermove
or
pointerrawupdate
event,
the
list
is
a
sequence
of
all
PointerEvent
s
that
were
coalesced
into
this
event;
otherwise
it
is
an
empty
list.
The
events
in
the
coalesced
event
list
will
have
increasing
timeStamp
s,
so
the
first
event
will
have
the
smallest
timeStamp
.
<style>
/* Disable intrinsic user agent direct manipulation behaviors (such as panning or zooming)
so that all events on the canvas element are given to the application instead. */
canvas { touch-action: none; }
</style>
<canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;"></canvas>
<script>
const canvas = document.getElementById("drawSurface"),
context = canvas.getContext("2d");
canvas.addEventListener("pointermove", (e)=> {
if (e.getCoalescedEvents) {
for (let coalesced_event of e.getCoalescedEvents()) {
paint(coalesced_event); // Paint all raw/non-coalesced points
}
} else {
paint(e); // Paint the final coalesced point
}
});
function paint(event) {
if(event.buttons>0) {
context.fillRect(event.clientX, event.clientY, 5, 5);
}
}
</
script
>
movementX
and
movementY
([
PointerLock
])
COULD
be
the
sum
of
those
of
all
the
coalesced
events.
The
order
of
all
these
dispatched
events
should
resemble
the
actual
order
of
the
original
events'
order.
For
example
if
a
pointerdown
event
causes
the
dispatch
for
the
coalesced
pointermove
events
the
user
agent
SHOULD
first
dispatch
one
pointermove
event
with
all
those
coalesced
events
of
a
pointerId
followed
by
the
pointerdown
event.
Here
is
an
example
of
the
actual
events
happening
with
increasing
timestamps
and
the
events
dispatched
by
the
user
agent:
| Actual events | Dispatched events |
|---|---|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=1)
coordinate
change
|
pointerrawupdate
(
pointerId
=1)
w/
one
coalesced
event
|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=1)
coordinate
change
|
pointerrawupdate
(
pointerId
=1)
w/
one
coalesced
event
|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=1)
button
press
|
pointermove
(
pointerId
=1)
w/
two
coalesced
events
pointermove
(
pointerId
=2)
w/
four
coalesced
events
pointerdown
(
pointerId
=1)
w/
zero
coalesced
events
|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=2)
coordinate
change
|
pointerrawupdate
(
pointerId
=2)
w/
one
coalesced
event
|
pointer
(
pointerId
=1)
button
release
|
pointermove
(
pointerId
=2)
w/
two
coalesced
events
pointerup
(
pointerId
=1)
w/
zero
coalesced
events
|
Some
user
agents
have
built-in
algorithms
which,
after
a
series
of
confirmed
pointer
movements,
can
make
a
prediction
(based
on
past
points,
and
the
speed/trajectory
of
the
movement)
what
the
position
of
future
pointer
movements
may
be.
Applications
can
use
this
information
with
the
method
to
speculatively
"draw
ahead"
to
a
predicted
position
to
reduce
perceived
latency,
and
then
discarding
these
predicted
points
once
the
actual
points
are
received.
getPredictedEvents
pointermove
events,
showing
the
user
agent's
predicted
future
points
(the
grey
circles).
A
PointerEvent
has
an
associated
predicted
event
list
(a
list
of
zero
or
more
PointerEvent
s).
If
this
event
is
a
pointermove
event,
it
is
a
sequence
of
PointerEvent
s
that
the
user
agent
predicts
will
follow
the
events
in
the
coalesced
event
list
in
the
future;
otherwise
it
is
an
empty
list.
While
pointerrawmove
events
may
have
a
non-empty
coalesced
event
list
,
their
predicted
event
list
will,
for
performance
reasons,
usually
be
an
empty
list.
The number of events in the list and how far they are from the current timestamp are determined by the user agent and the prediction algorithm it uses.
The
events
in
the
predicted
event
list
will
have
monotonically
increasing
timeStamp
s
[
DOM
],
so
the
first
event
will
have
the
smallest
timeStamp
.
All
predicted
events
have
a
timeStamp
that
is
greater
than
the
timeStamp
of
the
dispatched
pointer
event
that
the
method
was
called
on.
getPredictedEvents
Note that authors should only consider predicted events as valid predictions until the next pointer event is dispatched. It is possible, depending on how far into the future the user agent predicts events, that regular pointer events are dispatched earlier than the timestamp of one or more of the predicted events.
let predicted_points = [];
window.addEventListener("pointermove", function(event) {
// Clear the previously drawn predicted points.
for (let e of predicted_points.reverse()) {
clearPoint(e.pageX, e.pageY);
}
// Draw the actual movements that happened since the last received event.
for (let e of event.getCoalescedEvents()) {
drawPoint(e.pageX, e.pageY);
}
// Draw the current predicted points to reduce the perception of latency.
predicted_points = event.getPredictedEvents();
for (let e of predicted_points) {
drawPoint(e.pageX, e.pageY);
}
});
When
a
PointerEvent
is
created,
run
the
following
steps
for
each
event
in
the
coalesced
event
list
and
predicted
event
list
:
pointerId
,
pointerType
,
isPrimary
and
isTrusted
to
the
PointerEvent
's
pointerId
,
pointerType
,
isPrimary
and
isTrusted
.
cancelable
and
bubbles
attributes
to
false.
PointerEvent
.
A
PointerEvent
has
an
associated
coalesced
events
targets
dirty
and
an
associated
predicted
events
targets
dirty
flag.
When
an
event
is
created
they
must
be
initialized
to
false.
When
the
PointerEvent
's
target
is
changed,
set
coalesced
events
targets
dirty
and
predicted
events
targets
dirty
to
true.
When
the
method
is
called:
getCoalescedEvents
target
to
this
PointerEvent
's
target.
When
the
method
is
called:
getPredictedEvents
target
to
this
PointerEvent
's
target
.
The vast majority of web content existing today codes only to Mouse Events. The following describes an algorithm for how a user agent MAY map generic pointer input to mouse events for compatibility with this content.
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
and
contextmenu
events
(see
the
note
below).
The
click
event,
defined
in
[
UIEVENTS
],
and
the
contextmenu
event
are
not
considered
compatibility
mouse
events
as
they
are
typically
tied
to
user
interface
activation
and
are
fired
from
other
input
devices,
like
keyboards.
In
user
agents
that
support
firing
click
and/or
contextmenu
,
calling
preventDefault
during
a
pointer
event
typically
does
not
have
an
effect
on
whether
click
and/or
contextmenu
are
fired
or
not.
Because
they
are
not
compatibility
mouse
events,
user
agents
typically
fire
click
and
contextmenu
for
all
pointing
devices,
including
pointers
that
are
not
primary
pointers.
The
relative
ordering
of
these
high-level
events
(
click
,
contextmenu
,
focus
,
blur
,
etc.)
with
pointer
events
is
undefined
and
varies
between
user
agents.
For
example,
in
some
user
agents
contextmenu
will
often
follow
a
pointerup
,
in
others
it'll
often
precede
a
pointerup
or
pointercancel
,
and
in
some
situations
it
may
be
fired
without
any
corresponding
pointer
event
(such
as
a
keyboard
shortcut).
In
addition,
user
agents
may
apply
their
own
heuristics
to
determine
whether
or
not
a
click
or
contextmenu
event
should
be
fired.
Some
user
agents
may
only
fire
these
events
for
a
primary
pointer,
and
even
then
they
may
choose
not
to
fire
these
events
if
there
are
other
(non-primary)
pointers
of
the
same
type,
or
other
primary
pointers
of
a
different
type.
User
agents
may
determine
that
a
particular
action
was
not
a
"clean"
tap,
click
or
long-press
-
for
instance,
if
an
interaction
with
a
finger
on
a
touch
screen
includes
too
much
movement
while
the
finger
is
in
contact
with
the
screen
-
and
decide
not
to
fire
a
click
or
contextmenu
event.
These
aspects
of
user
agent
behavior
are
not
defined
in
this
specification,
and
they
may
differ
between
implementations.
Unless
otherwise
noted,
the
target
of
any
mapped
mouse
event
SHOULD
be
the
same
target
as
the
respective
pointer
event
unless
the
target
is
no
longer
participating
in
its
ownerDocument
's
tree.
In
this
case,
the
mouse
event
should
be
fired
at
the
original
target's
nearest
ancestor
node
(at
the
time
it
was
removed
from
the
tree)
that
still
participates
in
its
ownerDocument
's
tree,
meaning
that
a
new
event
path
(based
on
the
new
target
node)
is
built
for
the
mouse
event.
Authors
can
prevent
the
production
of
certain
compatibility
mouse
events
by
canceling
the
pointerdown
event.
mouseover
,
mouseout
,
mouseenter
,
and
mouseleave
events
are
never
prevented
(even
if
the
pointer
is
down).
While
only
the
primary
pointers
can
produce
compatibility
mouse
events,
multiple
primary
pointers
can
be
active
simultaneously,
each
producing
its
own
compatibility
mouse
events.
Since
all
these
compatibility
events
would
appear
to
MouseEvent
code
to
be
coming
from
a
single
mouse
device,
user
agents
are
encouraged
to
guarantee
that
the
compatibility
mouse
events
are
consistent
from
a
single
device
perspective.
For
mouse
transition
events
(i.e.,
mouseover
,
mouseout
,
mouseenter
and
mouseleave
),
this
means
the
entry/exit
state
for
every
event
target
is
valid
as
implied
by
[
UIEVENTS
].
Users
agents
SHOULD
guarantee
this
by
maintaining
the
effective
position
of
the
legacy
mouse
pointer
in
the
document
as
follows.
Right
before
firing
a
pointerdown
,
pointerup
or
pointermove
event,
or
a
pointerleave
event
at
the
window
,
the
user
agent
SHOULD
run
the
following
steps:
pointerdown
,
pointerup
or
pointermove
event
being
dispatched.
For
the
pointerleave
event,
unset
T
.
mouseover
,
mouseout
,
mouseenter
and
mouseleave
events
as
per
[
UIEVENTS
]
for
a
mouse
moving
from
the
current
effective
legacy
mouse
pointer
position
to
T
.
Consider
an
unset
value
of
either
current
effective
legacy
mouse
pointer
position
or
T
as
an
out-of-window
mouse
position.
Whenever a user agent is to dispatch a pointer event for a device that supports hover, it SHOULD run the following steps:
isPrimary
property
for
the
pointer
event
to
be
dispatched
is
false
then
dispatch
the
pointer
event
and
terminate
these
steps.
pointerdown
,
pointerup
or
pointermove
event,
or
a
pointerleave
event
at
the
window
,
dispatch
compatibility
mouse
transition
events
as
described
in
Tracking
the
effective
position
of
the
legacy
mouse
pointer
.
pointerdown
and
the
event
was
canceled
,
then
set
the
PREVENT
MOUSE
EVENT
flag
for
this
pointerType
.
PREVENT
MOUSE
EVENT
flag
is
not
set
for
this
pointerType
and
the
pointer
event
dispatched
was:
pointerdown
,
then
fire
a
mousedown
event.
pointermove
,
then
fire
a
mousemove
event.
pointerup
,
then
fire
a
mouseup
event.
pointercancel
,
then
fire
a
mouseup
event
at
the
window
.
pointerup
or
pointercancel
,
clear
the
PREVENT
MOUSE
EVENT
flag
for
this
pointerType
.
Some devices, such as most touchscreens, do not support hovering a coordinate (or set of coordinates) while not in the active state. Much existing content coded to mouse events assumes that a mouse is producing the events and thus certain qualities are generally true:
mousemove
event
on
an
element
before
clicking
it.
This requires that user agents provide a different mapping for these types of input devices. Whenever a user agent is to dispatch a pointer event for a device that does not support hover , it SHOULD run the following steps:
isPrimary
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
fire
a
mousemove
event
(for
compatibility
with
legacy
mouse-specific
code).
pointerdown
,
pointerup
or
pointermove
event,
or
a
pointerleave
event
at
the
window
,
dispatch
compatibility
mouse
transition
events
as
described
in
Tracking
the
effective
position
of
the
legacy
mouse
pointer
.
pointerdown
and
the
event
was
canceled
,
then
set
the
PREVENT
MOUSE
EVENT
flag
for
this
pointerType
.
PREVENT
MOUSE
EVENT
flag
is
not
set
for
this
pointerType
and
the
pointer
event
dispatched
was:
pointerdown
,
then
fire
a
mousedown
event.
pointermove
,
then
fire
a
mousemove
event.
pointerup
,
then
fire
a
mouseup
event.
pointercancel
,
then
fire
a
mouseup
event
at
the
window
.
pointerup
or
pointercancel
,
clear
the
PREVENT
MOUSE
EVENT
flag
for
this
pointerType
.
If the user agent supports both Touch Events (as defined in [ TOUCH-EVENTS ]) and Pointer Events, the user agent SHOULD NOT generate compatibility mouse events as described in this section as it is likely to introduce compatibility problems for sites that expect mouse events to be generated in accordance with the model outlined in [ TOUCH-EVENTS ].
The
activation
of
an
element
(
click
)
with
a
primary
pointer
that
does
not
support
hover
(e.g.
single
finger
on
a
touchscreen)
would
typically
produce
the
following
event
sequence:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
mousedown
pointermove
and
mousemove
events,
depending
on
movement
of
the
pointer
pointerup
mouseup
click
pointerout
pointerleave
mouseout
mouseleave
If,
however,
the
pointerdown
event
is
canceled
during
this
interaction
then
the
sequence
of
events
would
be:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
pointermove
events,
depending
on
movement
of
the
pointer
pointerup
click
pointerout
pointerleave
mouseout
mouseleave
tiltX
/
tiltY
and
altitudeAngle
/
azimuthAngle
This section is non-normative.
Depending
on
the
specific
hardware
and
platform,
user
agents
will
likely
only
receive
one
set
of
values
for
the
transducer
orientation
relative
to
the
screen
plane
-
either
tiltX
/
tiltY
or
altitudeAngle
/
azimuthAngle
.
The
following
basic
code
provides
an
initial
suggested
approach
for
converting
these
values.
/* Converting between tiltX/tiltY and altitudeAngle/azimuthAngle */
function spherical2tilt(altitudeAngle, azimuthAngle){
const radToDeg = 180/Math.PI;
let tiltXrad = 0;
let tiltYrad = 0;
if(altitudeAngle == 0){
// the pen is in the X-Y plane
if(azimuthAngle == 0 || azimuthAngle == 2*Math.PI){
// pen is on positive X axis
tiltXrad = Math.PI/2;
}
if(azimuthAngle == Math.PI/2){
// pen is on positive Y axis
tiltYrad = Math.PI/2;
}
if(azimuthAngle == Math.PI){
// pen is on negative X axis
tiltXrad = -Math.PI/2;
}
if(azimuthAngle == 3*Math.PI/2){
// pen is on negative Y axis
tiltYrad = -Math.PI/2;
}
if(azimuthAngle>0 && azimuthAngle<Math.PI/2){
tiltXrad = Math.PI/2;
tiltYrad = Math.PI/2;
}
if(azimuthAngle>Math.PI/2 && azimuthAngle<Math.PI){
tiltXrad = -Math.PI/2;
tiltYrad = Math.PI/2;
}
if(azimuthAngle>Math.PI && azimuthAngle<3*Math.PI/2){
tiltXrad = -Math.PI/2;
tiltYrad = -Math.PI/2;
}
if(azimuthAngle>3*Math.PI/2 && azimuthAngle<2*Math.PI){
tiltXrad = Math.PI/2;
tiltYrad = -Math.PI/2;
}
}
if(altitudeAngle != 0){
const tanAlt = Math.tan(altitudeAngle);
tiltXrad = Math.atan(Math.cos(azimuthAngle) / tanAlt);
tiltYrad = Math.atan(Math.sin(azimuthAngle) / tanAlt);
}
return {"tiltX":tiltXrad*radToDeg, "tiltY":tiltYrad*radToDeg};
}
function tilt2spherical(tiltX, tiltY){
const tiltXrad = tiltX * Math.PI/180;
const tiltYrad = tiltY * Math.PI/180;
// calculate azimuth angle
let azimuthAngle = 0;
if(tiltX == 0){
if(tiltY > 0){
azimuthAngle = Math.PI/2;
}
else if(tiltY < 0){
azimuthAngle = 3*Math.PI/2;
}
} else if(tiltY == 0){
if(tiltX < 0){
azimuthAngle = Math.PI;
}
} else if(Math.abs(tiltX) == 90 || Math.abs(tiltY) == 90){
// not enough information to calculate azimuth
azimuthAngle = 0;
} else {
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-90
const tanX = Math.tan(tiltXrad);
const tanY = Math.tan(tiltYrad);
azimuthAngle = Math.atan2(tanY, tanX);
if(azimuthAngle < 0){
azimuthAngle += 2*Math.PI;
}
}
// calculate altitude angle
let altitudeAngle = 0;
if (Math.abs(tiltX) == 90 || Math.abs(tiltY) == 90){
altitudeAngle = 0
} else if (tiltX == 0){
altitudeAngle = Math.PI/2 - Math.abs(tiltYrad);
} else if(tiltY == 0){
altitudeAngle = Math.PI/2 - Math.abs(tiltXrad);
} else {
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-90
altitudeAngle = Math.atan(1.0/Math.sqrt(Math.pow(Math.tan(tiltXrad),2) + Math.pow(Math.tan(tiltYrad),2)));
}
return {"altitudeAngle":altitudeAngle, "azimuthAngle":azimuthAngle};
}
This appendix discusses security and privacy considerations for Pointer Events implementations. The discussion is limited to security and privacy issues that arise directly from implementation of the event model, APIs and events defined in this specification.
Many of the event types defined in this specification are dispatched in response to user actions. This allows malicious event listeners to gain access to information users would typically consider confidential, e.g., the exact path/movement of a user's mouse/stylus/finger while interacting with a page.
Pointer events contain additional information (where supported by the user's device), such as the angle or tilt at which a pen input is held, the geometry of the contact surface, and the pressure exerted on the stylus or touch screen. Information about angle, tilt, geometry and pressure are directly related to sensors on the user's device, meaning that this specification allows an origin access to these sensors.
This sensor data, as well as the ability to determine the type of input mechanism (mouse, touch, pen) used, may be used to infer characteristics of a user, or of the user's device and environment. These inferred characteristics and any device/environment information may themselves be sensitive - for instance, they may allow a malicious site to further infer if a user is using assistive technologies. This information can also be potentially used for the purposes of building a user profile and/or attempting to "fingerprint" and track a particular user.
As mitigation, user agents may consider including the ability for users to disable access to particular sensor data (such as angle, tilt, pressure), and/or to make it available only after an explicit opt-in from the user.
Beyond these considerations, the working group believes that this specification:
This section is non-normative.
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
either
the
pen
has
physical
contact
with
the
digitizer,
or
at
least
one
button
is
depressed
while
hovering.
pointerId
)
to
produce
additional
events
within
the
document,
then
that
pointer
is
still
considered
active.
Examples:
preventDefault()
,
returning
false
in
an
event
handler,
or
other
means
as
defined
by
[
UIEVENTS
]
and
[
HTML
].
Measurable
properties
represent
values
relating
to
continuous
pointer
sensor
data
that
is
expressed
using
a
real
number
or
an
integer
from
a
large
domain.
For
pointer
events,
width
,
height
,
pressure
,
tangentialPressure
,
tiltX
,
tiltY
,
twist
,
altitudeAngle
,
azimuthAngle
,
and
the
[
UI-EVENTS
]
Mouse
Event
model
properties
screenX
,
screenY
,
clientX
,
clientY
are
measurable
properties.
In
contrast
pointerId
,
pointerType
,
isPrimary
,
and
the
[
UI-EVENTS
]
Mouse
Event
model
properties
button
,
buttons
,
ctrlKey
,
shiftKey
,
altKey
,
and
metaKey
are
not
considered
measurable
properties,
as
they
don't
relate
to
sensor
data.
Many thanks to lots of people for their proposals and recommendations, some of which are incorporated into this document. The group's Chair acknowledges contributions from the following past and present group members and participants: Mustaq Ahmed, Arthur Barstow, Matt Brubeck, Rick Byers, Marcos Cáceres, Cathy Chan, Bo Cupp, Domenic Denicola, Ted Dinklocker, Robert Flack, Dave Fleck, Ella Ge, Scott González, Kartikaya Gupta, Philippe Le Hégaret, Hayato Ito, Patrick Kettner, Patrick H. Lauke, Scott Low, Sangwhan Moon, Olli Pettay, Antoine Quint, Jacob Rossi, Kagami Sascha Rosylight, Doug Schepers, Ming-Chou Shih, Brenton Simpson, Dave Tapuska, Liviu Tinta, Asir Vedamuthu, Lan Wei, Navid Zolghadr
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 and Steve Wright.
This section is non-normative.
The following is an informative summary of substantial and major editorial changes between publications of this specification, relative to the [ PointerEvents2 ] specification. See the complete revision history of the Editor's Drafts of this specification .
touch-action
touch-action
definition
(scope
it
clearly
to
just
panning/zooming
actions)
click
/
contextmenu
and
user
agent
heuristics
pointerId
for
non-pointer
events
from
0
to
-1
touch-action
and
iframe/embedded
browsing
contexts
azimuthAngle
,
altitudeAngle
,
tiltX
,
tiltY
to
not
require
default
values
in
pointer
events
web
IDL
pointerrawupdate
and
getCoalescedEvents
click
,
auxclick
,
and
contextmenu
to
PointerEvent
altitudeAngle
/
azimuthAngle
getPredictedEvents
API.
getCoalescedEvents
API,
pointerrawupdate
event.
touch-action
values
(
pan-left
,
pan-right
,
pan-up
,
pan-down
)
and
clarified
behavior
of
existing
pan-x
and
pan-y
values.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: