I am trying to create a touch event for a unit test. After reading https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent, I expected that I would be able to do:
Update: This will not actually result in an instance of TouchEvent. lame.
I did it like this:
var type = 'start'; // or move, end
var event = document.createEvent('Event');
event.initEvent('touch' + type, true, true);
event.constructor.name; // Event (not TouchEvent)
You'll also need to set the touches on the event. That's another can of worms as some browsers support the document.createTouch and document.createTouchList methods and some don't. In browsers that don't you just create and array of JS objects that are "TouchEvent-like". This looks like:
var point = {x: 10, y: 10 };
event.touches = [{
target: someElement,
identifier: Date.now() + i,
pageX: point.x,
pageY: point.y,
screenX: point.x,
screenY: point.y,
clientX: point.x,
clientY: point.y
}]
I don't know if it works in other browsers but in chrome you can do something like
/* eventType is 'touchstart', 'touchmove', 'touchend'... */
function sendTouchEvent(x, y, element, eventType) {
const touchObj = new Touch({
identifier: Date.now(),
target: element,
clientX: x,
clientY: y,
radiusX: 2.5,
radiusY: 2.5,
rotationAngle: 10,
force: 0.5,
});
const touchEvent = new TouchEvent(eventType, {
cancelable: true,
bubbles: true,
touches: [touchObj],
targetTouches: [],
changedTouches: [touchObj],
shiftKey: true,
});
element.dispatchEvent(touchEvent);
}
const myElement = document.getElementById('foo')
sendTouchEvent(150, 150, myElement, 'touchstart');
sendTouchEvent(220, 200, myElement, 'touchmove');
sendTouchEvent(220, 200, myElement, 'touchend');
To test if a given browser supports Touch
and TouchEvent
if (typeof Touch !== 'undefined' &&
typeof TouchEvent !== 'undefined' &&
Touch.length === 1 &&
TouchEvent.length === 1) {
sendTouchEvent(200, 200, myElement, 'touchmove');
}
see Touch and TouchEvent constructors
I'm guessing the only way to do it without throwing an exception is to be more explicit in the type of event you wish to create:
var evt = document.createEvent('UIEvent');
evt.initUIEvent('touchstart', true, true);
The TouchEvent is a subclass of UIEvent.
Update
As mentioned above, while on an actual device (or emulating a device), one can easily create a TouchEvent using the standard document.createEvent
method.
So perhaps a try/catch would be in order:
try {
document.createEvent('TouchEvent');
} catch (e) {
console.log('No touching!');
}
It looks like
document.createEvent('TouchEvent');
works if you are using an actual mobile device or mobile emulation.