JavaScript TouchList
Interface
Learning outcomes:
- What is the
TouchList
interface - The
touches
object - The
changedTouches
object - The
targetTouches
object
Introduction
In the last chapter, JavaScript Touch Events — Basics, we covered the basics of working with touch events in JavaScript through the help of numerous practical examples. There we came across the three different TouchList
interfaces present on a TouchEvent
object, namely touches
, changedTouches
and targetTouches
.
Now in this chapter, our aim is to unravel the purpose of each of these three objects by drawing the exact difference between them and that through the help of numerous examples, as before.
So, let's get going...
Understanding TouchList
When we interact with an HTML document via a mouse pointer, some kind of mouse event is dispatched. Each such event is an instance of MouseEvent
which contains properties such as clientX
/ clientY
to represent the co-ordinates of the location of the mouse pointer right at the instance when the event occcured.
The same doesn't apply to a touch event. The reason is because devices typically support a feature called multi-touch which basically means that multiple fingers can interact with the screen simultaneously.
This means that there is absolutely no sense in providing properties such as clientX
/ clientY
directly on a TouchEvent
object.
Rather, it's necessary to provide a list of all the concerned touch points, each of which then contains these properties.
This is exactly the intuition behind TouchList
— it's an interface meant to hold multiple touch points.
TouchList
object is a Touch
instance that contains information regarding the underlying touch point.A TouchList
object has a length
property to our use holding the total number of elements in it. It also provides an iterator setup to allow for quick iteration over all the respective touch points.
However, as with many list interfaces in JavaScript, it doesn't inherit from the Array
interface and likewise doesn't have many of the useful array methods such as forEach()
, slice()
and so on.
There are a total of three different kinds of TouchList
instances — touches
, changedTouches
and targetTouches
.
Let's now see each of these instances one-by-one.
The touches
object
Although we have seen and worked with touches
for a quite a while in the previous chapter, let's review it once again.
In simple terms:
touches
is a TouchList
instance representing all the touch points that are currently in contact with the touch surface.It's useful when we want to determine the total number of points on the touch surface. Such a program was created in the previous chapter.
With the definition in mind, let's consider some examples to help us understand how touches
works.
First, let's see the touches
object upon the touchstart
event.
Consider the following code where we simply output the length of the touches
object on touchstart
:
var touchRegionElement = document.getElementById('touch-region');
var outputElement = document.getElementById('output');
touchRegionElement.addEventListener('touchstart', function(e) {
e.preventDefault();
outputElement.innerText = e.touches.length;
});
If we tap over the #touch-region
element here, the touchstart
event fires with touches
holding all the touch points currently in contact with the touch surface including the one that just fired the event.
e.preventDefault()
in the code above is to make sure that while interacting with the program, no kind of default browser action happens on the device, such as reloading the page when swipped down across the page.Simple so far.
Now let's consider the touchmove
event with the same setup as before:
var touchRegionElement = document.getElementById('touch-region');
var outputElement = document.getElementById('output');
touchRegionElement.addEventListener('touchmove', function(e) {
e.preventDefault();
outputElement.innerText = e.touches.length;
});
As we move the touch point over the whole document after initiating a touchstart
event inside #touch-point
, touches
once again represents a list of all touch points currently in contact with the surface.
Pretty intuitive, even in this case.
Now let's consider touches
on the touchend
event:
var touchRegionElement = document.getElementById('touch-region');
var outputElement = document.getElementById('output');
touchRegionElement.addEventListener('touchend', function(e) {
e.preventDefault();
outputElement.innerText = e.touches.length;
});
Here comes the catch: when we remove the touch point from the surface, touchend
fires, and since the touch point is no longer in contact with the surface, we can't obtain information (such as at what position it left) via the touches
object.
This is the main problem with touches
— it just doesn't provide us with this crucial information about the recently removed touch point. For that, we ought to refer to the changedTouches
object.
The changedTouches
object
As the name might suggest, changedTouches
is meant to hold all the touch points whose state has changed since the last event.
Defining it simply:
changedTouches
is a TouchList
instance representing all the touch points that fired the current event.Let's see some examples.
First for changedTouches
on the touchstart
event:
<div id="touch-region"></div>
<div><code>touches.length</code>: <span id="output1">0</span></div>
<div><code>changedTouches.length</code>: <span id="output2">0</span></div>
var touchRegionElement = document.getElementById('touch-region');
var output1Element = document.getElementById('output1');
var output2Element = document.getElementById('output2');
touchRegionElement.addEventListener('touchstart', function(e) {
e.preventDefault();
output1Element.innerText = e.touches.length;
output2Element.innerText = e.changedTouches.length;
});
For instance, if we tap on the surface with one touch point, a touchstart
event fires. Assuming that this touch point is still there on the surface (regardless of whether it has moved or not), if we tap with another touch point, touchstart
will fire once again.
In this event, touches
will contain two Touch
objects, however changedTouches
will contain only one i.e. the second touch point that caused this touchstart
event.
Next up, let's consider changedTouches
on the touchmove
event with the same setup as before:
var touchRegionElement = document.getElementById('touch-region');
var output1Element = document.getElementById('output1');
var output2Element = document.getElementById('output2');
touchRegionElement.addEventListener('touchmove', function(e) {
e.preventDefault();
output1Element.innerText = e.touches.length;
output2Element.innerText = e.changedTouches.length;
});
If we place two touch points on the #touch-region
element and then move only one touch point while keeping the other still, a touchmove
event will fire where changedTouches
will hold the moved touch point. In contrast, touches
will contain both the touch points.
Hence, changedTouches
allows us to determine which touch points have moved upon the current touchmove
event.
Let's now consider changedTouches
on touchend
:
var touchRegionElement = document.getElementById('touch-region');
var output1Element = document.getElementById('output1');
var output2Element = document.getElementById('output2');
touchRegionElement.addEventListener('touchend', function(e) {
e.preventDefault();
output1Element.innerText = e.touches.length;
output2Element.innerText = e.changedTouches.length;
});
The event where almost all touch-driven programs use changedTouches
is perhaps touchend
. It's what allows us to obtain information regarding the touch point that just exited the touch surface. This could then be used to, let's say, perform an array of different computations.
Here's a simple task:
Write a program listening to touch events over the entire document window and then outputting the x and y coordinates of the location where a touch point leaves the surface.
The output should be made inside the <div>
element as shown below
<div id="co-ordinates"></div>
in the format (x, y)
, where x
is the x co-ordinate and y
is the y co-ordinate.
var coordinatesElement = document.getElementById('co-ordinates');
window.addEventListener('touchend', function(e) {
coordinatesElement.innerText = '(' +
e.changedTouches[0].clientX +
', ' +
e.changedTouches[0].clientX +
')';
});
To summarize it all:
- On
touchstart
,changedTouches
holds all touch points that came into contact with the touch surface to cause the event. - On
touchmove
,changedTouches
holds all touch points that moved past their previous position to cause the event. - On
touchend
,changedTouches
holds all touch points that exited the touch surface to cause the event.
The targetTouches
object
It won't be wrong to say that of all three TouchList
instances on a TouchEvent
object, targetTouches
is the least useful.
Let's see what exactly is it.
targetTouches
is a TouchList
instance representing all the touch points that are currently in contact with the surface and have the same target as that of the current event.The main part here is the ending of the definition i.e. 'and have the same target as that of the current event.'
Didn't understand this?
Well, let's see an example.
Take a look at the following HTML and JavaScript:
<div id="touch-region"></div>
<div><code>targetTouches.length</code>: <span id="output1">0</span></div>
<div>Target element: <span id="output2">-</span></div>
var touchRegionElement = document.getElementById('touch-region');
var output1Element = document.getElementById('output1');
var output2Element = document.getElementById('output2');
window.addEventListener('touchstart', function(e) {
e.preventDefault();
output1Element.innerText = e.targetTouches.length;
output2Element.innerText = e.target.nodeName;
});
If we tap over the #touch-region
element with one touch point and then tap outside it with another one, somewhere on the document, at this point, touchstart
will fire with targetTouches
holding one single element which is the touch point outside #touch-region
.
Now with both the touch points still on the surface, if we tap with another touch point over #touch-region
(where there is already one touch point), touchstart
will fire again, this time with targetTouches
holding two elements.
That's because at this point, there will be a total two of touch points having #touch-region
(which is the target of the current touchstart
event) as their target.
So this is how targetTouches
works on touchstart
.
A similar description applies to touchmove
.
Upon touchend
, targetTouches
contains all those points that have the same target as the point that caused the current event.
Spread the word
Think that the content was awesome? Share it with your friends!
Join the community
Can't understand something related to the content? Get help from the community.