32

我搜索了过去 30 分钟,但没有找到解决方案。

我想touchstart在一个元素上触发一个事件。

这会触发touchstart事件:

var e = document.createEvent('MouseEvent');

e.initMouseEvent("touchstart", true, true, window, 1, screenX, screenY, clientX, clientY,
    ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);

target.dispatchEvent(e);

请注意,变量是由我的函数定义的

但这有一个问题。该event对象没有touches属性。所以这样的事情是行不通的:

var touch = e.touches[0];

有没有办法touchstart手动触发事件(它应该在 Android >= 4.0 和启用触摸的 Chrome [DevTools] 上工作)?

请注意,我不想使用像 jQuery 这样的任何框架。使用 jQuery 可以很容易地touchevent在元素上创建一个 ;)

4

5 回答 5

25

根据W3C

var e = document.createEvent('TouchEvent');

然后,也改变

e.initMouseEvent();

e.initTouchEvent();

因为你已经创建了一个touchstart事件。

W3C 链接说:

一些用户代理实现了一个 initTouchEvent 方法作为 TouchEvent 接口的一部分。当此方法可用时,脚本可以使用它来初始化 TouchEvent 对象的属性,包括其 TouchList 属性(可以使用从 createTouchList 返回的值进行初始化)。initTouchEvent 方法尚未标准化,但它可能会以某种形式出现在未来的规范中。

所以你可能不得不求助于e.initUIEvent('touchstart', true, true);
此外,官方规范还声明该TouchList对象是optional,并且可以使用该createTouchList方法手动创建。要向该列表添加触摸,您必须调用该createTouch方法,您将在其中传递所有坐标等:

6.1 方法

#createTouch
创建具有指定属性的 Touch 对象。
参数 | 类型 | 可空 | 可选 | 描述
查看 | 窗口代理 | ✘ | ✘ |
目标 | 事件目标 | ✘ | ✘ |
标识符| 长 | ✘ | ✘ |
第X页| 长 | ✘ | ✘ |
页Y | 长 | ✘ | ✘ |
屏幕X | 长 | ✘ | ✘ |
屏幕Y | 长 | ✘ | ✘ |
返回类型:触摸

#createTouchList
创建一个由零个或多个 Touch 对象组成的 TouchList 对象。不带参数调用此方法会创建一个 TouchList,其中没有对象且长度为 0(零)。

参数 | 类型 | 可空 | 可选 | 描述
触动 | 触摸 | ✘ | ✔ |
返回类型:TouchList

如果这不起作用,你可以试试这个:

var e = document.createEvent('UIEvent');
e.initUIEvent();

应该可以工作,它比任何时候都更有意义createEvent('MouseEvent')...
但是出于测试目的,为什么不打开您的 chrome 控制台并检查Emulate touch events,然后将用户代理覆盖到 Android 4。(Ctrl+Shift+j > 单击齿轮右下角,并选择覆盖,在那里你会找到你需要的所有设置)

由于触摸事件还有很长的路要走,但就它们变得标准化而言,事实证明该touches属性不是RO(还没有?),因此您可以使用此快速修复(OP 发现并与期望的结果):

var e = document.createEvent('TouchEvent');
e.touches = [{pageX: pageX, pageY: pageY}];

哪个,我认为(如果不是这样,我简直不敢相信)比:

e.touches = e.createTouchList(
    e.createTouch(window, target, 0, pageX, pageY, screenX, screenY)
);
于 2013-08-05T13:54:15.850 回答
18

我知道这已经得到解答,但我也很难找到这个问题的答案,并且接受的答案对我不起作用。最后,我找到的解决方案真的很简单,并且支持跨浏览器:

var e = new Event('touchstart');
target.dispatchEvent(e);

而已。再简单不过了。

于 2016-10-31T14:27:20.993 回答
4

我想出了这个解决方案(javascript native),对我有用

var el = document.getElementById('myDivId');
// desktop
el.click();

// mobile
if (window.matchMedia("(max-width: 768px)").matches) {
        // createEvent(), event.initEvent() are Depricated see Ref: [enter link description here][1]
        // var event = document.createEvent("Event"); 
        // event.initEvent("touchstart", false, true);
        // event.initEvent("touchend", false, true);
        // So the solution is:
        var event1 = new Event('touchstart');
        var event2 = new Event('touchend'); 
        el.dispatchEvent(event1); 
        el.dispatchEvent(event2);
  }
于 2019-06-11T15:57:22.217 回答
3

在 2019 年,我们可以使用TouchEventTouch.

Touch是一种实验技术

例如,

const touch = new Touch({
  identifier: "123",
  target: target,
});

const touchEvent = new TouchEvent("touchstart", {
  touches: [touch],
  view: window,
  cancelable: true,
  bubbles: true,
});

target.dispatchEvent(touchEvent);

我创建了gist。尝试简单。

于 2019-12-09T07:13:45.603 回答
-5

我们可以这样触发:

$playBtn.bind((is_touch_device) ? 'touchstart' : 'click', playfunction);
于 2013-08-05T13:55:36.963 回答