Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I programmatically create a TouchEvent in Chrome 41?

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:

document.createEvent('TouchEvent');

But I get this error:

Uncaught DOMException: Failed to execute 'createEvent' on 'Document': The provided event type ('TouchEvent') is invalid.

I saw Creating and firing touch events on a touch enabled browser?, which also seems to indicate that createEvent() is the way to go.

I also tried creating the event via constructor, which works for, say, MouseEvent and WheelEvent:

new window.TouchEvent()

But I get an error here, too:

Uncaught TypeError: Illegal constructor

I tried in Firefox 36, but based on http://caniuse.com/#search=touch, I wasn't surprised to see:

NotSupportedError: Operation is not supported

After running

document.createEvent('TouchEvent')

There is not event a window.TouchEvent constructor in Firefox, which is, again, not surprising.

Any ideas what I am doing wrong?

like image 797
exavatar Avatar asked Mar 12 '15 19:03

exavatar


3 Answers

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

like image 53
fhdhsni Avatar answered Nov 15 '22 17:11

fhdhsni


It looks like

document.createEvent('TouchEvent'); 

works if you are using an actual mobile device or mobile emulation.

like image 26
exavatar Avatar answered Nov 15 '22 19:11

exavatar


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!');

}
like image 33
shennan Avatar answered Nov 15 '22 18:11

shennan