JavaScript将触摸事件映射到鼠标事件
我正在使用与鼠标移动事件一起操作的YUI滑块。 我想让它响应touchmove事件(iPhone和Android)。 触摸移动事件发生时,如何产生鼠标移动事件? 我希望只是通过在顶部添加一些脚本,touchmove事件将被映射到鼠标移动事件,我不会有任何改变与滑块。
我确定这是你想要的:
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); }
我已经捕获了触摸事件,然后手动激发我自己的鼠标事件来匹配。 尽pipe代码不是特别通用的,但是适应大多数现有的拖放库以及可能是大多数现有的鼠标事件代码应该是微不足道的。 希望这个想法对于为iPhone开发Web应用程序的人来说非常方便。
更新:
在发布这个,我注意到,在所有触摸事件调用preventDefault
将阻止链接正常工作。 完全调用preventDefault
主要原因是停止滚动手机,只能通过touchmove
callback来调用。 这样做的唯一缺点是iPhone有时会在拖动原点上显示hoverpopup窗口。 如果我发现一种方法来防止这种情况,我会更新这个post。
第二次更新:
我find了CSS属性来closures标注: -webkit-touch-callout
。
按照@Mickey Shine的回答, Touch Punch提供触摸事件到点击事件的映射。 它的build立是为了把这个支持到jQuery UI中,但是代码是提供信息的。
对于未来的用户,可以使用下面的代码来回顾一下:
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]; }; }; })();
然后在事件中使用如下:
$(".yourDiv").on(eventMap.mouseup, function(event) { //your code }
我终于find了一种使用Mickey的解决scheme而不是他的初始化函数的方法。 在这里使用init函数。
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); }
如果您看到“ filter_div
”是我们有图表范围filter的图表区域,并且只在该区域中,我们是否要重写我们的触摸控件!
谢谢Mickey。 这是一个很好的解决scheme。
为了让@Mickey的代码在Edge和Internet Explorer上工作,在要发生模拟的元素的.css中添加以下几行:
.areaWhereSimulationHappens { overflow: hidden; touch-action: none; -ms-touch-action: none; }
这些行防止边缘和IE的默认触摸。 但是,如果将其添加到错误的元素中,则也会禁用滚动(这在边缘和触摸设备上的IE上默认会发生)。