mousemove 和 mouseup事件应该绑定到document元素上
不能绑定到当前拖动的元素上,否则当鼠标快速移出菜单,mousemove 和 mouseup事件就不会触发了
let initMeunLeft = 0; // 菜单初始位置
let initMenuTop = 0;
let menuDOM: HTMLDivElement; // 整个菜单
let menuBar: HTMLDivElement // 菜单上面的 div,点击拖动
function colorMenuMouseDown(event: MouseEvent) {
console.log('1', event)
initPointX = event.clientX // 鼠标点下的位置
initPointY = event.clientY
menuBar = event.target as HTMLDivElement
menuDOM = menuBar.parentElement as HTMLDivElement // 父元素是整个菜单
initMeunLeft = menuDOM.offsetLeft
initMenuTop = menuDOM.offsetTop
//mousemove 和 mouseup事件应该绑定到document元素上
document.addEventListener('mousemove', colorMenuMouseMove) // 给菜单上面的 title 加上 事件
document.addEventListener('mouseup', colorMenuMouseUp)
event.preventDefault() //加上这个防止内容被选中
}
function colorMenuMouseMove(event: MouseEvent) {
const moveWidth = event.clientX - initPointX // 移动的距离
const moveHeight = event.clientY - initPointY //
menuDOM.style.left = initMeunLeft + moveWidth + 'px' // 更新菜单的位置
menuDOM.style.top = initMenuTop + moveHeight + 'px'
console.log('2', menuDOM)
event.preventDefault() //加上这个防止内容被选中
}
function colorMenuMouseUp(event: MouseEvent) {
console.log('3', event)
//mousemove 和 mouseup事件应该绑定到document元素上
document.removeEventListener('mousemove', colorMenuMouseMove)
document.removeEventListener('mouseup', colorMenuMouseUp)
}
这是我之前写的一个拖动代码.参考下
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=11,chrome=1" />
<title> 页面名称 </title>
<style type="text/css">
#cf {
background-color: #c99;
}
#kkk {
position: absolute;
left: 100px;
top: 400px;
width: 200px;
height: 100px;
background-color: #f9c;
}
.range {
width: 300px;
height: 20px;
border-radius: 20px;
border: 2px solid #66f;
background-color: #ccf;
}
.range .slider {
width: 20px;
height: 20px;
border-radius: 20px;
background-color: #f00;
}
</style>
</head>
<body>
<canvas id="cf" width="400" height="350"></canvas>
<div class="range"><div class="slider"></div></div>
<div id="kkk"></div>
<script type="text/javascript">
!function () {
function Drag(opt) {
this.el = typeof opt.el=="string" ? document.querySelector(opt.el) : opt.el;
this.start = opt.start || function(){};
this.move = opt.move || function(){};
this.end = opt.end || function(){};
this.el.style.touchAction = opt.touchAction || "none";
this.startEvent = this.startFun.bind(this);
this.moveEvent = this.moveFun.bind(this);
this.endEvent = this.endFun.bind(this);
this.dragging = false;
this.startPos = null;
this.prevPos = null;
this.moveBindEl = Drag.isTouch ? this.el : document;
this.el.addEventListener(Drag.eventType.start, this.startEvent, false);
}
Drag.isTouch = "ontouchstart" in document;
Drag.eventType = Drag.isTouch
? { start: "touchstart", move: "touchmove", end: "touchend" }
: { start: "mousedown" , move: "mousemove", end: "mouseup" };
Drag.prototype.startFun = function (e) {
if (this.dragging) return;
this.moveBindEl.addEventListener(Drag.eventType.move, this.moveEvent, false);
this.moveBindEl.addEventListener(Drag.eventType.end, this.endEvent, false);
this.dragging = true;
var pos = this.position(e);
this.startPos = pos;
if (this.start.call(this.el,e,pos,this)!==true && !Drag.isTouch)
e.preventDefault();
this.prevPos = pos;
};
Drag.prototype.moveFun = function (e) {
if (!this.dragging) return;
var pos = this.position(e);
if (this.move.call(this.el,e,pos,this)!==true && !Drag.isTouch)
e.preventDefault();
this.prevPos = pos;
};
Drag.prototype.endFun = function (e) {
if (!this.dragging) return;
this.moveBindEl.removeEventListener(Drag.eventType.move, this.moveEvent, false);
this.moveBindEl.removeEventListener(Drag.eventType.end, this.endEvent, false);
this.dragging = false;
if (e) {
var pos = e!==true ? this.position(e) : this.prevPos;
this.end.call(this.el,e,pos,this);
}
};
Drag.prototype.position = function (e) {
var et = Drag.isTouch ? e[e.type!="touchend"?"targetTouches":"changedTouches"][0] : e;
var pos = {
screenX: et.screenX,
screenY: et.screenY,
clientX: et.clientX,
clientY: et.clientY,
pageX: et.pageX,
pageY: et.pageY
};
pos.offset = this.offset.bind(this,pos);
return pos;
};
Drag.prototype.offset = function (et,obj) {
obj = obj || this.el;
var r = obj.getBoundingClientRect();
return {
x: et.clientX - r.left,
y: et.clientY - r.top
};
};
window.Drag = Drag;
}();
///////////////////////////////////////
var canvas = document.getElementById("cf");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 3;
ctx.lineCap= "round";
var obj = new Drag({
el: canvas,
start: function (e,pos,t) {
},
move: function (e,pos,t) {
var p0 = t.prevPos.offset();
var p1 = pos.offset();
ctx.beginPath();
ctx.moveTo(p0.x,p0.y);
ctx.lineTo(p1.x,p1.y);
ctx.stroke();
},
end: function (e,pos,t) {
}
});
/////////////////////////////////////////
var uk = {};
var obj2 = new Drag({
el: "#kkk",
start: function (e,pos,t) {
uk = pos.offset();
},
move: function (e,pos,t) {
this.style.left = pos.pageX - uk.x + "px";
this.style.top = pos.pageY - uk.y + "px";
},
end: function (e,pos,t) {
}
});
//////////////////////////////////////////////
var obj3 = new Drag({
el: ".range",
touchAction: "pan-y",
start: function (e,pos,t) {
},
move: function (e,pos,t) {
var p = pos.offset();
var obj = this.querySelector(".slider");
var max = this.clientWidth - obj.offsetWidth;
var x = Math.max(Math.min(p.x - Math.floor(obj.offsetWidth/2),max),0);
obj.style.marginLeft = x + "px";
},
end: function (e,pos,t) {
}
});
</script>
</body>
</html>