拖拽 = 鼠标按下 + 鼠标移动 + 鼠标弹上
这样就完成了一个拖拽任务,想实现拖拽,自然实现上面的3个动作,便可以模拟拖拽效果,对应JavaScript中的语法就是需要实现这3个动作:
onmousedown , onmousemove , onmouseup
import React, { useEffect, useState } from 'react';
import './window.less';
export default function Page() {
let [act, setact] = useState(-1);
let [menu, setmenu] = useState(false);
let [visiable, setvisiable] = useState(false);
let [img, setimg] = useState(0);
const drag = () => {
//获取对应的节点信息
let target: any = document.querySelector(".modal");
let context = document.querySelector(".context");
//鼠标按下以后
target.onmousedown = function (event: any) {
var event = event || window.event;//兼容性的写法
//获取鼠标当前的坐标值:
var X1 = event.clientX;
var Y1 = event.clientY;
//获取盒子的偏倚位置
var L = target.offsetLeft; //左偏倚的内容
var T = target.offsetTop;//上面的偏倚值内容
console.log("坐标值", X1, Y1)
console.log("偏移值:", L, T);
//开始移动鼠标
document.onmousemove = function (event) {
//获取鼠标当前的坐标值:
var X2 = event.clientX;
var Y2 = event.clientY;
//移动盒子的位置
target.style.left = X2 - X1 + L + "px";
target.style.top = Y2 - Y1 + T + "px";
}
document.onmouseup = function(){
document.onmousemove = null;
}
}
}
useEffect(() => {
drag();//调用方法
})
return (
<div className='window' style={{ backgroundImage: 'url(/imgs/wall-' + img + '.jpg)' }} onClick={() => {
setact(-1);
setmenu(false);
}}>
<div className="content">
<div className={act === 1 ? 'icon act' : 'icon'} onClick={(event) => { event.stopPropagation(); setact(1) }} onDoubleClick={(event) => { event.stopPropagation(); setvisiable(true) }}>
<img src="/imgs/skin.png" />
<p>换肤</p>
</div>
<div className={act === 2 ? 'icon act' : 'icon'} onClick={(event) => { event.stopPropagation(); setact(2) }}>
<img src="/imgs/2.png" />
<p>浏览器</p>
</div>
</div>
{/* 模态框的操作 */}
<div className='modal' style={{ display: visiable ? "block" : "none" }}>
<header><span>换皮肤</span> <span style={{ float: "right", fontSize: "20px", color: "#FFF" }} onClick={() => setvisiable(false)}>X</span></header>
<div className='context' style={{ backgroundImage: 'url(/imgs/wall-' + img + '.jpg)' }}>
<img src='/imgs/wall-0.jpg' onClick={() => setimg(0)} />
<img src='/imgs/wall-1.jpg' onClick={() => setimg(1)} />
<img src='/imgs/wall-2.jpg' onClick={() => setimg(2)} />
</div>
</div>
<div className="task">
<div className='menu'>
{
menu ?
<div className='menu-list'>
<img src="/imgs/1.png" />
</div>
:
<></>
}
<img src="/imgs/Windows.png" onClick={(e) => { e.stopPropagation(); setmenu(true) }} />
</div>
</div>
</div>
);
}
如果页面上有文字的话,拖拽物体会将文字选中,这效果岂不是怪怪的,没错,这是因为拖拽的时候触发了浏览器的默认选择事件,所以,在拖拽的时候,我们要清除这个默认事件 e.stopPropagation()
window.less
.window {
width: 100vw;
height: 100vh;
background-repeat: no-repeat;
cursor: pointer;
.content {
width: 100vw;
height: 100vh;
.icon {
width: 120px;
text-align: center;
position: absolute;
left: 20px;
img {
width: 60px;
}
p {
color: #FAFAFA;
text-align: center;
line-height: 30px;
}
}
.icon:nth-child(1) {
top: 30px;
}
.icon:nth-child(2) {
top: 150px;
}
.icon.act {
background: rgba(50, 50, 50, .8);
}
}
.modal {
width: 500px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 1px 3px 5px #333;
header {
width: 100%;
height: 40px;
background: #008800;
}
.context {
width: 100%;
height: 300px;
background-repeat: no-repeat;
img {
width: 100px;
}
}
}
.task {
width: 100vw;
background: #303030;
position: fixed;
bottom: 0px;
box-sizing: border-box;
padding: 10px;
.menu {
position: relative;
.menu-list {
width: 20vw;
height: 35vh;
background: #345;
position: absolute;
bottom: 70px;
left: -10px;
box-shadow: 1px 3px 5px #333;
border-top-right-radius: 10px;
transition: all 1s ease;
}
}
img {
height: 60px;
}
}
}
页面效果
拖拽是对中间的div盒子进行拖拽的