schepers@4: mbrubeck@74: schepers@4: mbrubeck@101: Touch Events version 1 schepers@4: mbrubeck@74: mbrubeck@20: art@170: schepers@4: mbrubeck@20: mbrubeck@66: schepers@4: schepers@4: art@130:
art@171: This specification is the 24 January 2013 Last Call Working Draft. art@171: The comment period for this Last Call Working Draft is 14 February 2013. art@143: art@171: The art@171: 15 December 2011 Candidate Recommendation art@171: was returned to Last Call Working Draft because of art@171: issues art@171: found during the implementation and interoperability testing phases. art@144: art@171: The WG will complete its art@171: test suite art@171: and two or more independent implementations must pass each test before art@171: the specification is published as a Proposed Recommendation. art@171: The group will also create an Implementation Report. art@130:
art@130: schepers@4:
mbrubeck@103: The Touch Events specification defines a set of low-level events that josh@85: represent one or more points of contact with a touch-sensitive surface, josh@85: and changes of those points with respect to the surface and any DOM josh@85: elements displayed upon it (e.g. for touch screens) or associated with it josh@85: (e.g. for drawing tablets without displays). It also addresses josh@85: pen-tablet devices, such as drawing tablets, with consideration toward josh@85: stylus capabilities. schepers@4:
schepers@5: smoon@81:
smoon@81:

Introduction

smoon@81: josh@85:

josh@85: User Agents that run on terminals which provide touch input to use web josh@87: applications typically use interpreted mouse events to allow users josh@85: to access interactive web applications. However, these interpreted josh@85: events, being normalized data based on the physical touch input, tend josh@87: to have limitations on delivering the intended user experience. josh@85: Additionally, it is not possible to handle concurrent input regardless josh@87: of device capability, due to constraints of mouse events: both josh@87: system level limitations and legacy compatibility. josh@85:

smoon@81: josh@85:

josh@85: Meanwhile, native applications are capable of handling both cases with josh@85: the provided system APIs. josh@85:

josh@85: josh@85:

josh@85: The Touch Events specification provides a solution to this problem by josh@86: specifying interfaces to allow web applications to directly handle touch josh@85: events, and multiple touch points for capable devices. josh@85:

smoon@81:
smoon@81: art@28:
josh@85:

josh@85: This specification defines conformance criteria that apply to a single josh@85: product: the user agent that implements josh@85: the interfaces that it contains. josh@85:

art@28: josh@85:

josh@85: Implementations that use ECMAScript to implement the APIs defined in josh@85: this specification must implement them in a manner consistent with the josh@85: ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]] as josh@85: this specification uses that specification and terminology. josh@85:

art@28: josh@85:

josh@85: A conforming implementation is required to implement all fields josh@85: defined in this specification. josh@85:

art@28:
mbrubeck@20: schepers@4:
mbrubeck@46:

Touch Interface

josh@85:

mbrubeck@139: This interface describes an individual touch point for a touch mbrubeck@106: event. Touch objects are immutable; after one is created, its mbrubeck@106: attributes must not change. josh@85:

mbrubeck@20: mbrubeck@46:
schepers@9:
readonly attribute long identifier
schepers@5:
mbrubeck@91: An identification number for each touch point. mbrubeck@20: mbrubeck@91: When a touch point becomes active, it must be assigned an mbrubeck@91: identifier that is distinct from any other active touch mbrubeck@91: point. While the touch point remains active, all events that mbrubeck@91: refer to it must assign it the same identifier. schepers@5:
schepers@4: mbrubeck@139:
readonly attribute EventTarget target
mbrubeck@139:
mbrubeck@139: The Element on which the touch point started when it mbrubeck@139: was first placed on the surface, even if the touch point has mbrubeck@139: since moved outside the interactive area of that element. mbrubeck@139:
mbrubeck@139: schepers@9:
readonly attribute long screenX
schepers@5:
smoon@123: The horizontal coordinate of point relative to the screen in pixels schepers@5:
schepers@9:
readonly attribute long screenY
schepers@5:
smoon@123: The vertical coordinate of point relative to the screen in pixels schepers@5:
schepers@4: schepers@9:
readonly attribute long clientX
schepers@5:
smoon@123: The horizontal coordinate of point relative to the viewport in pixels, smoon@123: excluding any scroll offset schepers@5:
schepers@9:
readonly attribute long clientY
schepers@5:
smoon@123: The vertical coordinate of point relative to the viewport in pixels, smoon@123: excluding any scroll offset schepers@5:
schepers@5: schepers@9:
readonly attribute long pageX
schepers@5:
smoon@123: The horizontal coordinate of point relative to the viewport in pixels, smoon@123: including any scroll offset schepers@5:
schepers@9:
readonly attribute long pageY
schepers@5:
smoon@123: The vertical coordinate of point relative to the viewport in pixels, smoon@123: including any scroll offset schepers@5:
schepers@5:
schepers@5:
schepers@5: schepers@5:
schepers@9:

TouchList Interface

josh@85:

josh@85: This interface defines a list of individual points of contact for a mbrubeck@106: touch event. TouchList objects are immutable; after one is mbrubeck@106: created, its contents must not change. josh@85:

mbrubeck@20: schepers@5:
schepers@5:
readonly attribute unsigned long length
schepers@5:
mbrubeck@47: returns the number of Touches in the list schepers@5:
mbrubeck@103:
getter Touch item (in unsigned long index)
schepers@5:
mbrubeck@103: returns the Touch at the specified index in the list schepers@5:
mbrubeck@103:
Touch identifiedTouch (in long identifier)
schepers@5:
mbrubeck@103: returns the first Touch item in the list whose identifier property matches the specified identifier schepers@5:
schepers@5:
schepers@5:
schepers@5: schepers@5:
schepers@9:

TouchEvent Interface

josh@85:

josh@85: This interface defines the touchstart, touchend, mbrubeck@101: touchmove, and touchcancel event types. mbrubeck@106: TouchEvent objects are immutable; after one is created and mbrubeck@106: initialized, its attributes must not change. josh@85:

schepers@5: schepers@6:
schepers@9:
readonly attribute TouchList touches
schepers@4:
josh@85: a list of Touches for every point of contact currently smoon@99: touching the surface. schepers@4:
schepers@9:
readonly attribute TouchList targetTouches
schepers@4:
mbrubeck@96: a list of Touches for every point of contact that is touching mbrubeck@96: the surface and started on the element that is the mbrubeck@96: target of the current event. schepers@4:
schepers@9:
readonly attribute TouchList changedTouches
schepers@4:
mbrubeck@96:

mbrubeck@96: a list of Touches for every point of contact which contributed mbrubeck@96: to the event. mbrubeck@96:

mbrubeck@96:

mbrubeck@96: For the touchstart event this must be a list of the touch mbrubeck@96: points that just became active with the current event. For the mbrubeck@96: touchmove event this must be a list of the touch points that cathy@121: have moved since the last event. For the touchend and cathy@121: touchcancel events this must be a list of the touch points cathy@121: that have just been removed from the surface. mbrubeck@96:

schepers@4:
mbrubeck@23: mbrubeck@30:
readonly attribute boolean altKey
mbrubeck@30:
josh@85: true if the alt (Alternate) key modifier is activated; josh@85: otherwise false mbrubeck@30:
mbrubeck@30:
readonly attribute boolean metaKey
mbrubeck@30:
josh@85: true if the meta (Meta) key modifier is activated; josh@85: otherwise false. On some platforms this attribute may josh@85: map to a differently-named key modifier. mbrubeck@30:
mbrubeck@30:
readonly attribute boolean ctrlKey
mbrubeck@30:
josh@85: true if the ctrl (Control) key modifier is activated; josh@85: otherwise false mbrubeck@30:
mbrubeck@30:
readonly attribute boolean shiftKey
mbrubeck@30:
josh@85: true if the shift (Shift) key modifier is activated; josh@85: otherwise false mbrubeck@30:
schepers@4:
smoon@100: smoon@100:
smoon@100:

Usage Examples

smoon@100: smoon@100:

smoon@100: The examples below demonstrate the relations between the different smoon@100: TouchList members defined in a TouchEvent. smoon@100:

smoon@100: smoon@100:
smoon@100:

touches and targetTouches of a TouchEvent

smoon@100: smoon@100:

smoon@100: This example demonstrates the utility and relations between the smoon@100: touches and targetTouches members defined in the TouchEvent smoon@100: interface. The following code will generate different output based smoon@100: on the number of touch points on the touchable element and the document: smoon@100:

smoon@100: smoon@100:
smoon@100:                   <div id='touchable'>
smoon@100:                       This element is touchable.
smoon@100:                   </div>
smoon@100:           
smoon@100:                   document.getElementById('touchable').addEventListener('touchstart', function(ev) {
smoon@100: 
smoon@100:                       if (ev.touches.item(0) == ev.targetTouches.item(0))
smoon@100:                       {
smoon@100:                           /**
smoon@100:                            * If the first touch on the surface is also targeting the
smoon@100:                            * "touchable" element, the code below should execute.
smoon@100:                            * Since targetTouches is a subset of touches which covers the
smoon@100:                            * entire surface, TouchEvent.touches >= TouchEvents.targetTouches
smoon@100:                            * is always true.
smoon@100:                            */
smoon@100: 
smoon@100:                           document.write('Hello Touch Events!');
smoon@100:                       }
smoon@100: 
smoon@100:                       if (ev.touches.length == ev.targetTouches.length)
smoon@100:                       {
smoon@100:                           /**
smoon@100:                            * If all of the active touch points are on the "touchable"
smoon@100:                            * element, the length properties should be the same.
smoon@100:                            */
smoon@100: 
smoon@100:                           document.write('All points are on target element')
smoon@100:                       }
smoon@100: 
smoon@100:                       if (ev.touches.length > 1)
smoon@100:                       {
smoon@100:                           /**
smoon@100:                            * On a single touch input device, there can only be one point
smoon@100:                            * of contact on the surface, so the following code can only
smoon@100:                            * execute when the terminal supports multiple touches.
smoon@100:                            */
smoon@100: 
smoon@100:                           document.write('Hello Multiple Touch!');
smoon@100:                       }
smoon@100: 
smoon@100:                   }, false);
smoon@100:               
smoon@100:
smoon@100: smoon@100:
smoon@100:

changedTouches of a TouchEvent

smoon@100: smoon@100:

smoon@100: This example demonstrates the utility of changedTouches and it's relation smoon@100: with the other TouchList members of the TouchEvent interface. smoon@100: The code is a example which triggers whenever a touch point is removed smoon@100: from the defined touchable element: smoon@100:

smoon@100: smoon@100:
smoon@100:                   <div id='touchable'>
smoon@100:                       This element is touchable.
smoon@100:                   </div>
smoon@100:               
smoon@100:                   document.getElementById('touchable').addEventListener('touchend', function(ev) {
smoon@100: 
smoon@100:                       /**
smoon@100:                        * Example output when three touch points are on the surface,
smoon@100:                        * two of them being on the "touchable" element and one point
smoon@100:                        * in the "touchable" element is lifted from the surface:
smoon@100:                        *
smoon@100:                        * Touch points removed: 1
smoon@100:                        * Touch points left on element: 1
smoon@100:                        * Touch points left on document: 2
smoon@100:                        */
smoon@100: 
smoon@100:                       document.write('Removed: ' + ev.changedTouches.length);
smoon@100:                       document.write('Remaining on element: ' + ev.targetTouches.length);
smoon@100:                       document.write('Remaining on document: ' + ev.touches.length);
smoon@100: 
smoon@100:                   }, false);
smoon@100:               
smoon@100:
smoon@100: smoon@100:
schepers@8: smoon@126:
smoon@126:

List of TouchEvent types

smoon@126: smoon@126:

smoon@126: The following table provides a summary of the types of possible smoon@126: TouchEvent types defined in this specification. All events smoon@126: should accomplish the bubbling phase. Some events are not cancelable smoon@126: (see preventDefault). smoon@126:

smoon@126: smoon@126: smoon@126: art@130: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: mbrubeck@131: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: mbrubeck@131: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126: smoon@126:
Event TypeSync / AsyncBubbling phaseTrusted proximal event target typesDOM interfaceCancelableDefault Action
touchstartSyncYesDocument, ElementTouchEventYesundefined
touchendSyncYesDocument, ElementTouchEventYes smoon@126: Varies: mousemove (If point has been moved), mousedown, smoon@126: mouseup, click smoon@126:
touchmoveSyncYesDocument, ElementTouchEventYesundefined
touchcancelSyncYesDocument, ElementTouchEventNonone
smoon@126:
smoon@126: schepers@5:
josh@85:

The touchstart josh@85: event

josh@85:

josh@85: A user agent must dispatch this event type to indicate when the user josh@85: places a touch point on the touch surface. josh@85:

mbrubeck@55: josh@85:

mbrubeck@93: The target of this event must be an Element. If the touch mbrubeck@93: point is within a frame, the event should be dispatched to an element mbrubeck@93: in the child browsing context of that frame. josh@85:

mbrubeck@95: mbrubeck@95:

mbrubeck@95: If the preventDefault method is called on this event, it mbrubeck@95: should prevent any default actions caused by any touch events mbrubeck@95: associated with the same active touch point, including mouse mbrubeck@95: events or scrolling. mbrubeck@95:

schepers@5:
mbrubeck@20: schepers@5:
schepers@9:

The touchend event

josh@85:

josh@85: A user agent must dispatch this event type to indicate when the user josh@85: removes a touch point from the touch surface, also including josh@85: cases where the touch point physically leaves the touch surface, such josh@85: as being dragged off of the screen. josh@85:

mbrubeck@54: josh@85:

cathy@121: The target of this event must be the same Element on cathy@121: which the touch point started when it was first josh@85: placed on the surface, even if the touch point has since moved josh@85: outside the interactive area of the target element. josh@85:

mbrubeck@55: josh@85:

josh@85: The touch point or points that were removed must be included josh@85: in the changedTouches attribute of the TouchEvent, and josh@85: must not be included in the touches and targetTouches josh@85: attributes. josh@85:

schepers@5:
mbrubeck@20: schepers@5:
schepers@9:

The touchmove event

josh@85:

josh@85: A user agent must dispatch this event type to indicate when the user josh@85: moves a touch point along the touch surface. josh@85:

mbrubeck@54: josh@85:

cathy@121: The target of this event must be the same Element on cathy@121: which the touch point started when it was first josh@85: placed on the surface, even if the touch point has since moved josh@85: outside the interactive area of the target element. josh@85:

mbrubeck@54: josh@85:

josh@85: Note that the rate at which the user agent sends touchmove josh@85: events is implementation-defined, and may depend on hardware josh@85: capabilities and other implementation details. josh@85:

mbrubeck@95: mbrubeck@95:

mbrubeck@95: If the preventDefault method is called on the first mbrubeck@95: touchmove event of an active touch point, it should mbrubeck@95: prevent any default action caused by any touchmove event mbrubeck@95: associated with the same active touch point, such as scrolling. mbrubeck@95:

schepers@5:
mbrubeck@20: schepers@5:
mbrubeck@61:

The touchcancel event

josh@85:

josh@85: A user agent must dispatch this event type to indicate when a touch josh@85: point has been disrupted in an implementation-specific manner, such as josh@85: a synchronous event or action originating from the UA canceling the josh@85: touch, or the touch point leaving the document window into a josh@85: non-document area which is capable of handling user interactions. josh@85: (e.g. The UA's native user interface, plug-ins) A user agent may josh@85: also dispatch this event type when the user places more touch josh@85: points on the touch surface than the device or implementation is josh@85: configured to store, in which case the earliest Touch object josh@85: in the TouchList should be removed. josh@85:

cathy@121: cathy@121:

cathy@121: The target of this event must be the same Element on cathy@121: which the touch point started when it was first cathy@121: placed on the surface, even if the touch point has since moved cathy@121: outside the interactive area of the target element. cathy@121:

cathy@121: cathy@121:

cathy@121: The touch point or points that were removed must be included cathy@121: in the changedTouches attribute of the TouchEvent, and cathy@121: must not be included in the touches and targetTouches cathy@121: attributes. cathy@121:

schepers@5:
schepers@4:
mbrubeck@20: mbrubeck@68:
mbrubeck@115:

Extensions to the Document Interface

josh@85:

mbrubeck@115: The Document interface [[!DOM-LEVEL-3-CORE]] contains methods mbrubeck@115: by which the user can create Touch and TouchList mbrubeck@115: objects. josh@85:

mbrubeck@68: mbrubeck@115:
mbrubeck@68:
Touch createTouch()
mbrubeck@68:
mbrubeck@68: Creates a Touch object with the specified attributes. mbrubeck@68:
mbrubeck@68:
AbstractView view
mbrubeck@68:
EventTarget target
mbrubeck@68:
long identifier
mbrubeck@68:
long pageX
mbrubeck@68:
long pageY
mbrubeck@68:
long screenX
mbrubeck@68:
long screenY
mbrubeck@68:
mbrubeck@68:
mbrubeck@68: mbrubeck@68:
TouchList createTouchList()
mbrubeck@68:
josh@85: Creates a TouchList object containing the specified josh@85: Touch objects. mbrubeck@68:
mbrubeck@68:
Touch[] touches
mbrubeck@68:
mbrubeck@68:
mbrubeck@68: mbrubeck@68:
TouchList createTouchList()
mbrubeck@68:
mbrubeck@68: Creates a TouchList object containing a single Touch. mbrubeck@68:
mbrubeck@68:
Touch touch
mbrubeck@68:
mbrubeck@68:
mbrubeck@68:
mbrubeck@68:
mbrubeck@68: mbrubeck@35:
mbrubeck@35:

Interaction with Mouse Events

josh@85:

josh@85: The user agent may dispatch both touch events and mouse events josh@85: [[!DOM-LEVEL-2-EVENTS]] in response to the same user input. If the josh@85: user agent dispatches both touch events and mouse events in response to josh@85: a single user action, then the touchstart event type must be josh@85: dispatched before any mouse event types for that action. If the josh@85: preventDefault method of touchstart or touchmove josh@85: is called, the user agent should not dispatch any mouse event that josh@85: would be a consequential result of the the prevented touch event. josh@85:

mbrubeck@58: art@142:

art@142: If a Web application can process touch events, it can intercept them, art@142: and no corresponding mouse events would need to be dispatched by the art@142: user agent. If the Web application is not specifically written for art@142: touch input devices, it can react to the subsequent mouse events instead. art@142:

art@142: josh@85:

mbrubeck@98: If the user agent intreprets a sequence of touch events as a click, mbrubeck@98: then it should dispatch mousemove, mousedown, mbrubeck@98: mouseup, and click events (in that order) at the location mbrubeck@98: of the touchend event for the corresponding touch input. If the mbrubeck@98: contents of the document have changed during processing of the touch mbrubeck@98: events, then the user agent may dispatch the mouse events to a mbrubeck@98: different target than the touch events. mbrubeck@97:

mbrubeck@97: mbrubeck@97:

josh@85: The default actions and ordering of any further touch and mouse events josh@85: are implementation-defined, except as specified elsewhere. josh@85:

mbrubeck@35:
mbrubeck@35: schepers@10:
schepers@10:

Glossary

mbrubeck@20: schepers@10:
mbrubeck@91:
active touch point
josh@85:
mbrubeck@91: A touch point which is currently on the screen and is being mbrubeck@91: tracked by the user agent. The touch point becomes active when the mbrubeck@91: user agent first dispatches a touchstart event indicating its mbrubeck@91: appearance. It ceases to be active after the user agent dispatches a mbrubeck@91: touchend or touchcancel event indicating that the touch mbrubeck@91: point is removed from the surface or no longer tracked. schepers@10:
mbrubeck@20: schepers@12:
touch point
josh@85:
josh@85: The coordinate point at which a pointer (e.g finger or stylus) josh@85: intersects the target surface of an interface. This may apply to a josh@85: finger touching a touch-screen, or an digital pen writing on a piece josh@85: of paper. josh@85:
smoon@124: smoon@124:
preventDefault
smoon@124:
smoon@124: If a event is cancelable, the preventDefault method is used to signify smoon@124: that the event is to be canceled, and any default actions defined in the smoon@124: user agent as a result of this event, or consequential events from the smoon@124: canceled event will not occur. Calling this method on non-cancelable smoon@124: events will have no effect. smoon@124:
schepers@10:
schepers@10:
mbrubeck@20: mbrubeck@71:
mbrubeck@71:

Issues

josh@85:

josh@85: The working group maintains a list of open issues in this specification. These issues may be josh@85: addressed in future revisions of the specification. josh@85:

mbrubeck@71:
mbrubeck@71: mbrubeck@71:
schepers@4:

Acknowledgements

schepers@4:

josh@85: Many thanks to the WebKit engineers for developing the model used as a josh@85: basis for this spec, Neil Roberts (SitePen) for his summary of WebKit josh@86: touch events, Peter-Paul Koch (PPK) for his write-ups and suggestions, josh@85: Robin Berjon for developing the ReSpec.js spec authoring tool, and the WebEvents WG for their many josh@85: contributions. schepers@4:

mbrubeck@20: josh@85:

josh@85: Many others have made additional comments as the spec developed, which josh@85: have led to steady improvements. Among them are Matthew Schinckel, josh@85: Andrew Grieve, and Cathy Chan. If I inadvertently omitted your name, josh@85: please let me know. josh@85:

schepers@4:
schepers@4: schepers@4: