JavaScript mapping touch events to mouse events

安稳与你 提交于 2019-11-26 14:12:49
Mickey Shine

I am sure this is what you want:

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
    switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type = "mousemove"; break;        
        case "touchend":   type = "mouseup";   break;
        default:           return;
    }

    // initMouseEvent(type, canBubble, cancelable, view, clickCount, 
    //                screenX, screenY, clientX, clientY, ctrlKey, 
    //                altKey, shiftKey, metaKey, button, relatedTarget);

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                                  first.screenX, first.screenY, 
                                  first.clientX, first.clientY, false, 
                                  false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() 
{
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);    
}

I've captured the touch events and then manually fired my own mouse events to match. Although the code isn't particularly general purpose as is, it should be trivial to adapt to most existing drag and drop libraries, and probably most existing mouse event code. Hopefully this idea will come in handy to people developing web applications for the iPhone.

Update:

In posting this, I noticed that calling preventDefault on all touch events will prevent links from working properly. The main reason to call preventDefault at all is to stop the phone from scrolling, and you can do that by calling it only on the touchmove callback. The only downside to doing it this way is that the iPhone will sometimes display its hover popup over the drag origin. If I discover a way to prevent that, I'll update this post.

Second Update:

I've found the CSS property to turn off the callout: -webkit-touch-callout.

Along the lines of @Mickey Shine's answer, Touch Punch provides mapping of touch events to click events. It's built to put this support into jQuery UI, but the code is informative.

For future users, who comeback here the following code might be used :

var eventMap = {};

(function(){
var eventReplacement = {
    "mousedown": ["touchstart mousedown", "mousedown"],
    "mouseup": ["touchend mouseup", "mouseup"],
    "click": ["touchstart click", "click"],
    "mousemove": ["touchmove mousemove", "mousemove"]
};


for (i in eventReplacement) {
    if (typeof window["on" + eventReplacement[i][0]] == "object") {
        eventMap[i] = eventReplacement[i][0];
    } 
    else {
        eventMap[i] = eventReplacement[i][1];
    };
 };
})();

And then in the events use like following :

$(".yourDiv").on(eventMap.mouseup, function(event) {
      //your code
}
Sana

I finally found a way to get this working using Mickey's solution but instead of his init function. Use the init function here.

function init() {
    document.getElementById('filter_div').addEventListener("touchstart", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchmove", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchend", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchcancel", touchHandler, true);
}

If you see 'filter_div' is the chart area where we have the chart range filter and only in that area do we want to rewrite our touch controls!

Thank you Mickey. It was a great solution.

For making @Mickey's code work on Edge and internet explorer, add the following lines in .css of the element where you want the simulation to happen:

.areaWhereSimulationHappens {
    overflow: hidden;
    touch-action: none;
    -ms-touch-action: none;
}

These lines prevent the default touch for edge and IE. But if you add it to the wrong element, then it also disables scroll (which happens by default on edge and IE on touch devices).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!