实现思路:首先需要点击后开始拖动,也就是给一个变量mousedown的时候为true,mouseup的时候为false,然后在mousemove的时候判断这个变量是否存在,需要鼠标点击当前元素的任何一个位置得到当前这个点距当前元素最左边和最上边的距离(需要拖动元素的e.clientX-需要拖动元素的.offsetLeft),然后拖动的时候通过监听document里的clientX/clientY-你刚才得到的距左边/顶部的距离拿到的这个差值就是你需要设置的left和top值,而且重要的一点除了mousedown是监听的需要拖动的元素外,其他的mousemove和mouseup监听的都必须是document
另外为了让手机也使用你也同时需要监听touchstart、touchmove、touchend
1.在mousedown的时候拿到你当前点距当前元素的距离
2.在mousemove移动后通过e.clientX/e.clientY-上面获取到的距离就是我们的left/top的值
案例1:拖拽弹窗
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拖拽</title>
<style>
body{
height: 100vh;
width: 100%;
overflow: hidden;
}
*{
margin: 0;
}
.box{
width: 200px;
height: 200px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
{
let view = {
el: '.box',
init(){
this.box = document.querySelector(this.el)
this.document = document
}
}
let controller = {
moving: false,
init(view){
this.view = view
this.view.init()
this.bindEvent()
},
preventDefaultEvent(){
// 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
if (this.event && this.event.preventDefault) {
this.event.preventDefault();
} else {
this.event.returnValue = false;
}
// 禁止事件冒泡
if (this.event && this.event.stopPropagation) {
this.event.stopPropagation();
} else {
window.event.cancelBubble = true;
}
},
touchOrMouse(){
this.clientEvent = this.event.touches ? this.event.touches[0] : this.event
this.clientX = this.clientEvent.clientX
this.clientY = this.clientEvent.clientY
},
down(e){
this.moving = true
this.event = e || window.event
// 要同时适配mousedown和touchstart事件
this.touchOrMouse()
this.left = this.clientX - this.view.box.offsetLeft
this.top = this.clientY - this.view.box.offsetTop
this.preventDefaultEvent()
},
move(e){
this.event = e || window.event
if(this.moving){
this.touchOrMouse()
this.left1 = this.clientX - this.left
this.top1 = this.clientY - this.top
this.view.box.style.left = `${this.left1}px`
this.view.box.style.top = `${this.top1}px`
}
},
end(e){
this.moving = false
},
bindEvent(){
this.view.box.addEventListener('mousedown',this.down.bind(this))
this.view.box.addEventListener('touchstart',this.down.bind(this))
this.view.document.addEventListener('mousemove',this.move.bind(this))
this.view.document.addEventListener('touchmove',this.move.bind(this))
this.view.document.addEventListener('mouseup',this.end.bind(this))
this.view.document.addEventListener('touchend',this.end.bind(this))
}
}
controller.init(view)
}
</script>
</body>
</html>
案例2:进度条拖拽
<!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=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
display: flex;
}
.progress-wrapper{
position: relative;
height: 3vh;
background: #ccc;
flex: 1;
margin: 40px;
}
.progress-bg,.progress-dot{
position: absolute;
left: 0;
}
.progress-bg{
height: 100%;
background: green;
}
.progress-dot{
height: 6vh;
width: 12px;
background: green;
top: 50%;
transform: translateY(-50%);
}
</style>
</head>
<body>
<div class="progress-wrapper">
<div class="progress-bg"></div>
<div class="progress-dot"></div>
</div>
<script>
{
let view = {
el: '.progress-wrapper',
init(){
this.box = document.querySelector(this.el)
this.bg = this.box.children[0]
this.dot = this.box.children[1]
}
}
let controller = {
moving: false,
document: null,
init(view){
this.view = view
this.view.init()
this.document = document
this.bindEvent()
},
preventDefaultEvent(){
// 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
if (this.event && this.event.preventDefault) {
this.event.preventDefault();
} else {
this.event.returnValue = false;
}
// 禁止事件冒泡
if (this.event && this.event.stopPropagation) {
this.event.stopPropagation();
} else {
window.event.cancelBubble = true;
}
},
touchOrMouse(){
this.clientEvent = this.event.touches ? this.event.touches[0] : this.event
this.clientX = this.clientEvent.clientX
},
down(e){
this.moving = true
this.event = e || window.event
this.touchOrMouse()
this.left = this.clientX - this.view.dot.offsetLeft
},
move(e){
this.event = e || window.event
this.touchOrMouse()
if(this.moving){
this.left1 = this.clientX -this.left
this.view.dot.style.left = `${this.left1}px`
this.view.bg.style.width = `${this.left1}px`
}
},
end(e){
this.moving = false
},
bindEvent(){
this.view.dot.addEventListener('mousedown',this.down.bind(this))
this.view.dot.addEventListener('touchstart',this.down.bind(this))
this.document.addEventListener('mousemove',this.move.bind(this))
this.document.addEventListener('touchmove',this.move.bind(this))
this.document.addEventListener('mouseup',this.end.bind(this))
this.document.addEventListener('touchend',this.end.bind(this))
}
}
controller.init(view)
}
</script>
</body>
</html>
网友评论