如何在 Chrome 中创建 TouchEvent?

How to Create a TouchEvent in Chrome?

W3C specification声明initTouchEvent如下:

void initTouchEvent (in DOMString    type,
                     in boolean      canBubble,
                     in boolean      cancelable,
                     in AbstractView view,
                     in long         detail,
                     in boolean      ctrlKey,
                     in boolean      altKey,
                     in boolean      shiftKey,
                     in boolean      metaKey,
                     in TouchList    touches,
                     in TouchList    targetTouches,
                     in TouchList    changedTouches);

然而,当我在 Chrome 44 中尝试时:

var e = document.createEvent('TouchEvent');
e.initTouchEvent("touchstart", true, true, window, 1,
                 false, false, false, false, touches, null, null);

其中 touches 是有效的 TouchList,这是 Chrome 创建的:

> TouchEvent {}
    altKey: false
    bubbles: true
    cancelBubble: false
    cancelable: true
    changedTouches: null
    charCode: 0
    ctrlKey: true
    currentTarget: null
    defaultPrevented: false
    detail: 0
    eventPhase: 0
    keyCode: 0
    layerX: 0
    layerY: 0
    metaKey: false
    pageX: 0
    pageY: 0
    path: Array[0]
    returnValue: true
    shiftKey: false
    srcElement: null
    target: null
    targetTouches: null
    timeStamp: 1435339572699
    touches: null
    type: "[object Window]"
    view: null
    which: 0

仔细查看 type 字段。似乎 Chrome 没有遵循规范,其中第 4 个参数变成了类型而不是第一个参数。

这给我们带来了一个问题,即我实际上如何在 Chrome 中创建一个 TouchEvent,因为它不符合规范?

通过查看 Chromium source and Qiita (in Japanese),它的参数似乎是这样排列的:

initTouchEvent (TouchList touches,
                TouchList targetTouches,
                TouchList changedTouches,
                String type,
                Window view,
                number screenX,
                number screenY,
                number clientX,
                number clientY,
                boolean ctrlKey, 
                boolean altKey,
                boolean shiftKey,
                boolean metaKey);

注意 Chrome 不遵循 W3C 规范。


Chromium 源代码中的相关部分:

TouchEvent.cpp 第 63 行:

void TouchEvent::initTouchEvent(ScriptState* scriptState, TouchList* touches, TouchList* targetTouches,
        TouchList* changedTouches, const AtomicString& type,
        PassRefPtrWillBeRawPtr<AbstractView> view,
        int, int, int, int,
        bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
    if (dispatched())
        return;

    if (scriptState->world().isIsolatedWorld())
        UIEventWithKeyState::didCreateEventInIsolatedWorld(ctrlKey, altKey, shiftKey, metaKey);

    bool cancelable = true;
    if (type == EventTypeNames::touchcancel)
        cancelable = false;

    initUIEvent(type, true, cancelable, view, 0);

    m_touches = touches;
    m_targetTouches = targetTouches;
    m_changedTouches = changedTouches;
    m_ctrlKey = ctrlKey;
    m_altKey = altKey;
    m_shiftKey = shiftKey;
    m_metaKey = metaKey;
}