Javascript 如何在Chrome41中以编程方式创建TouchEvent?

Javascript 如何在Chrome41中以编程方式创建TouchEvent?,javascript,google-chrome,Javascript,Google Chrome,我正在尝试为单元测试创建一个触摸事件。阅读之后,我希望自己能够做到: document.createEvent('TouchEvent'); 但我得到了这个错误: 未捕获的DomeException:未能对“文档”执行“createEvent”:提供的事件类型(“TouchEvent”)无效 我看到了,这似乎也表明createEvent()是一条出路 我还尝试通过构造函数创建事件,该构造函数适用于MouseEvent和wheeleevent: new window.TouchEvent()

我正在尝试为单元测试创建一个触摸事件。阅读之后,我希望自己能够做到:

document.createEvent('TouchEvent');
但我得到了这个错误:

未捕获的DomeException:未能对“文档”执行“createEvent”:提供的事件类型(“TouchEvent”)无效

我看到了,这似乎也表明createEvent()是一条出路

我还尝试通过构造函数创建事件,该构造函数适用于MouseEvent和wheeleevent:

new window.TouchEvent()
但我这里也有一个错误:

未捕获类型错误:非法构造函数

我尝试了Firefox 36,但基于这一点,我并不惊讶地发现:

NotSupportedError:不支持该操作

跑步后

document.createEvent('TouchEvent')
Firefox中没有event.TouchEvent构造函数,这也不足为奇


知道我做错了什么吗?

我想不引发异常的唯一方法是在您希望创建的事件类型中更加明确:

var evt = document.createEvent('UIEvent');

evt.initUIEvent('touchstart', true, true);
是的一个子类

更新

如上所述,在实际设备(或模拟设备)上,可以使用标准的
document.createEvent
方法轻松创建TouchEvent

因此,也许应该尝试一下:

try {

  document.createEvent('TouchEvent');

} catch (e) {

  console.log('No touching!');

}

更新:这实际上不会导致TouchEvent的实例。瘸子

我是这样做的:

var type = 'start'; // or move, end
var event = document.createEvent('Event');
event.initEvent('touch' + type, true, true);     
event.constructor.name; // Event (not TouchEvent)
您还需要设置事件的触动。这是另一种蠕虫,因为有些浏览器支持document.createTouch和document.createTouchList方法,有些则不支持。在不需要的浏览器中,您只需创建一个JS对象数组,这些对象类似于TouchEvent。这看起来像:

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
}]
看起来像

document.createEvent('TouchEvent'); 

如果您使用的是实际的移动设备或移动仿真,则此功能有效

我不知道它是否适用于其他浏览器,但在chrome中,您可以执行以下操作

/* 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');
测试给定浏览器是否支持
触摸
触摸事件

if (typeof Touch !== 'undefined' &&
    typeof TouchEvent !== 'undefined' &&
    Touch.length === 1 &&
    TouchEvent.length === 1) {
       sendTouchEvent(200, 200, myElement, 'touchmove');
}

请看

我曾想过这样做,但我希望这取决于对象本身的类型;我们正在进行一些事件合成,还使用了HammerJS,因此多个事件类具有相同的类型,如“touchstart”。我当然可以使用UIEvent通过测试,但它没有正确的测试精神。:)
evt.constructor==TouchEvent
/touch/.test(evt.type)
之间真的有这样的区别吗?JavaScript并不真正处理经典继承,所以在我看来,您正在尝试将一个方形的钉子塞进一个圆形的孔中——即使它很精力充沛:-)不,没有太大区别,除了重新定义event.type与我尝试测试的代码不匹配;我可能不得不改变这一点。看来你和深南都有同样的方法,我感谢你的帮助。这是一个变通办法,并不完全是我工作的目的。但是,我可能被它卡住了。关于你的更新:是的,这就是问题所在。我想要一个TouchEvent的实例,而不是依赖事件列表。键入(仅限Windows 8+),如果您没有实际设备,则可以创建一个调用的程序。它将创建Chrome能够识别并允许您创建TouchEvents的虚拟触摸设备。谢谢。这是目前的正确答案。在Chrome 56中工作。这看起来不错,但对我来说不起作用:我不能像你那样创建Touch对象(
提供的参数与调用目标的任何签名都不匹配
),因为es6这样声明:
声明var Touch:{prototype:Touch;new():Touch;}。你用的是什么版本?@MichaSchwab我刚刚在chromium 59上测试了这个代码片段,它仍然有效。我记得在typescript中也有同样的问题(应该填写一个问题)。我声明了自己的接口来解决这个问题。你可以找到它,是的,我在Typescript中也有这个问题。好主意!我会试试的,谢谢!如何将元素上的2个touchstart设置为缩放?