function onMouse (eventType) {
if (ev.type === 'mousedown') {
} else if (ev.type === 'mouseup') {
} else if (ev.type === 'mousemove' && !initiated) {
ev.type === 'mousedown' || // 按下时更新
!eventTarget || // 如果事件对象不存在
(eventTarget && !eventTarget.dispatchEvent)
if (eventTarget.closest('[data-no-touch-simulate]') == null) {
triggerTouch(eventType, ev);
if (ev.type === 'mouseup') {
function triggerTouchEvent (eventName, mouseEvent) {
const touchEvent = new Event(eventName, { bubbles: true, cancelable: true })
touchEvent.altKey = mouseEvent.altKey
touchEvent.ctrlKey = mouseEvent.ctrlKey
touchEvent.metaKey = mouseEvent.metaKey
touchEvent.shiftKey = mouseEvent.shiftKey
touchEvent.touches = getActiveTouches(mouseEvent)
touchEvent.targetTouches = getActiveTouches(mouseEvent)
touchEvent.changedTouches = createTouchList(mouseEvent)
eventTarget.dispatchEvent(touchEvent)
const Touch = function Touch (target, identifier, pos, deltaX, deltaY) {
this.identifier = identifier
this.clientX = pos.clientX + deltaX
this.clientY = pos.clientY + deltaY
this.screenX = pos.screenX + deltaX
this.screenY = pos.screenY + deltaY
this.pageX = pos.pageX + deltaX
this.pageY = pos.pageY + deltaY
touchList.item = function (index) {
return this[index] || null
touchList.identifiedTouch = function (id) {
return this[id + 1] || null
function createTouchList (mouseEv) {
const touchList = TouchList()
touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0))
function getActiveTouches (mouseEvent) {
if (mouseEvent.type === 'mouseup') {
return createTouchList(mouseEvent)
window.addEventListener('mousedown', onMouse('touchstart'), true)
window.addEventListener('mousemove', onMouse('touchmove'), true)
window.addEventListener('mouseup', onMouse('touchend'), true)