如何在移动端触发touch事件时转换为执行PC端的mouse事件?

前言

  前段时间,博主使用一款国产JavaScript插件jTopo来画拓扑图,在整个过程中,入了不少坑,也填过不少坑。
  先给大家简单介绍下:
  jTopo(Javascript Topology library)是一款完全基于HTML5 Canvas的关系、拓扑图形化界面开发工具包。jTopo关注于数据的图形展示,它是面向开发人员的,需要进行二次开发。使用jTopo很简单,可以快速创建一些关系图、拓扑等相关图形化的展示。只要您的数据之间存在有关联关系,都可以使用jTopo来进行人性化、图形化的展示。
  jTopo的目标:

  • 简单好用。
  • 灵活扩展。
  • 轻松开发出类似Visio、在线脑图、UML建模等类似工具。
  • 为大数据可视化提供解决方案。

  以上介绍来自jTopo官网,对jTopo想进一步了解 >> 传送门

  嘿嘿~ 广告打多了,说下我的总体感受吧。

  • 优点: 轻量,不依赖其他库;使用简单,学习成本低;在绘制拓扑图方面,独树一帜;当然,最重要的还是因为开源
  • 缺点: 正如官网所讲,文档API不够详细;不支持移动端touch事件;留下了不少坑,作者却不再更新……

场景

  言归正传,博主所做的项目中,有一模块,专门用来把抄控器下的节点绘制成拓扑图。博主使用Ajax获取到后端传过来的数据包,因为数据量庞大,层级极深,多达15层,拓扑节点成百上千个,所以绘制的拓扑图必然要支持拖动和缩放,以及要对单个节点进行详情信息的展示操作。博主查阅参考了几款有名的图表框架,例如:D3,Echarts等,在拓扑图处理方面都不尽人意,库又非常大,相比之下,jTopo简直是为博主项目量身打造。
  参考着官网的案例,博主使用jTopo绘制的拓扑图在PC端实现了拖动、缩放、节点的鼠标操作等,效果演示如下。
PC端拓扑图效果演示

  但是, 将项目移植到移动端,发现拓扑图却无法实现拖动、缩放等操作,博主均用平板和手机测试过,移动端不方便录屏,如下移动端效果演示使用Chrome浏览器模拟的平板。
移动端拓扑图效果演示1

  jTopo官网提供的源码只有压缩版,没有注释,即便格式化了,改起来也特别麻烦。而且,一般情况下,我们所引用的第三方库,都是只用不改。一番思考,博主决定在移动端上拓扑图触发touch事件时将其转化为执行PC端的mouse事件,这样即可在移动端用手指实现拓扑图的拖动效果。

详细步骤:

Step One:defining transformOriginalEvent()

  定义方法:transformOriginalEvent(),将touch事件转换为对应的mouse事件,具体代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// transformOriginalEvent
function transformOriginalEvent(event, eventType) {
if (!event.originalEvent || !event.originalEvent.targetTouches || event.originalEvent.targetTouches.length != 1)
return false;
var targetObj = event.originalEvent.targetTouches[0];
var clientX = targetObj.clientX, clientY = targetObj.clientY, screenX = targetObj.screenX, screenY = targetObj.screenY;

var newMouseEvent = new MouseEvent(eventType, {
clientX: clientX,
clientY: clientY,
screenX: screenX,
screenY: screenY,
button: 0,
buttons: 0
});

return newMouseEvent;
}

Step Two:defining targetEleTouchToMouse()

  大家都知道,移动端的touchstart、touchmove、touchend事件分别对应PC端的mousedown、mousemove、mouseup事件。
  我们调用第一步定义的方法:transformOriginalEvent(),将目标元素的touchstart事件触发时转化为mousedown事件,将touchmove事件触发时转化为mousemove事件,将目标元素的touchend事件触发时转化为mouseup事件,具体代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function targetEleTouchToMouse(targetElement) {
targetElement.on('touchstart', function (e) {
console.log('touchstart');
var mouseEvent = transformOriginalEvent(e, 'mousedown');
if (mouseEvent != null) {
$(this)[0].dispatchEvent(mouseEvent);
}
});

targetElement.on('touchmove', function (e) {
e.preventDefault();
console.log('touchmove');
var mouseEvent = transformOriginalEvent(e, 'mousemove');
if (mouseEvent != null) {
$(this)[0].dispatchEvent(mouseEvent);
}
});

targetElement.on('touchend', function (e) {
console.log('touchend');
var mouseEvent = transformOriginalEvent(e, 'mouseup');
if (mouseEvent != null) {
$(this)[0].dispatchEvent(mouseEvent);
}
});
}

Step There:use targetEleTouchToMouse()

  使用jQuery选择器,选择一个DOM元素,调用targetEleTouchToMouse()方法。

1
2
var touchTargetEle = $('#canvas');
targetEleTouchToMouse(touchTargetEle);

最终的效果演示:

移动端拓扑图效果演示2

备注: 此方法依赖jQuery。

  从最终的效果演示图中大家可以看到touchend事件触发时控制台打印出报错信息,在实际测试中,博主发现touchend竟然无效!!但最终效果却实现了。
  需要将移动端触发touch事件转换成执行PC端的mouse事件的同学们,我们一起探讨探讨,更多的坑等你哦~

-------- The End --------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%