前言
这个是我在做一个d3的demo的时候出现的一个问题吧,就是想要他实现拖动d3的叶子节点,但是的话,不触发他的点击事件。
在这里,我想过以下两种种方案:
- 设计监听mousedown,mouseup的计时器
- 设计监听mousedown,mouseup的位置
但是很快就实践了一下,然后测试不同的电脑:
- 设定计时器的话,会导致不知道设多长时间,一开始设定100ms,但是发现,有些鼠标点击速度不够,但是设置超过100ms的话,点击快的已经拉动完了,这样的体验感很差。
- 接下来就只能设计一下监听位置了,这时候,又有一个问题,d3当中绑定节点的事件,是没有接口给你拿到他的事件对象的。这时候,我就想到一个好方法,就是设计监听其父组件的事件就可以了,反正都会冒泡的。接下来就实践一下吧。
js当中的鼠标事件
在这里,我就介绍一些常用的吧,更多的,可以看看js权威指南或者js高级教程
- click: 用户单击主鼠标键(一般是左边)或者按下回车键时触发
- dblclick: 用户双击主鼠标键(一般是左边)或者按下回车键时触发
- mousedown: 用户按下任意鼠标按钮触发,键盘不能触发
- mousemove: 鼠标在元素内移动就不断的触发,键盘不能触发
- mouseup: 用户松开鼠标键时候触发,键盘不能触发
然后鼠标主键点击触发的事件依次是
- mousedown
- mouseup
- click
实现方法
<!--dom结构-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="father">
<div id="child"></div>
</div>
</body>
</html>
// 先编写一个跨浏览器绑定事件的对象吧
var EventUtil = {
// 添加绑定事件
addHandle: function(element, type, handler) {
if(element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
// 移除绑定事件
removeHandler: function(element, type, handler) {
if(element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
}
计时器实现方法
var timer, // 计时器
toClick; // 判断是否跳转
EventUtil.addHandle(document.getElementById("child"), "mousedown", function () {
toClick = true;
timer = setTimeout("toClick = false",100);
})
EventUtil.addHandle(document.getElementById("child"), "mouseup",function(node){
clearTimeout(timer);
if(toClick){
console.log("click")
}
})
计算位置实现方法
var beginX, // 起始位置
beginY,
endX, // 结束位置
endY;
// 计算起始位置和结束位置
document.getElementById("father").addEventListener("mousedown", function (e) {
beginX = e.clientX;
beginY = e.clientY;
},false)
document.getElementById("father").addEventListener("mouseup", function (e) {
endX = e.clientX;
endY = e.clientY;
},false)
// 判断是否要跳转
EventUtil.addHandle(document.getElementById("child"), "click", function(){
if(!isdrag(beginX, beginY, endX, endY)){
console.log("click");
}
})
// 判断是否拖动了,这里我设置了1px,大家可以根据自己来进行修改吧
function isdrag(x1, y1, x2 , y2) {
if(Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) <= 1) {
return false;
}
return true;
}
总结
其实,觉得这两种方法可以配合使用更好,因为可能有些用户拉回到了原来的位置,大家可以自行多发挥,而且代码比较短和简单,我就不进行多的封装了,大家自行了解一下就行,有什么疑问可以留言。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。