使用ondrag 事件实现拖拽,以及自定义鼠标图片
效果如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 200px;
height: 100px;
position: relative;
background-color: red;
margin: 100px;
cursor: pointer;
}
* {
margin: 0;
}
body {
margin-top: 100px;
}
.inner {
background-color: green;
width: 50px;
height: 50px;
margin-left: 50px;
/* 自定义鼠标图片,图片不能太大,否则显示不了 */
cursor:url('./02.jpg'), auto;
}
</style>
</head>
<body>
<!-- draggable 属性规定元素是否可拖动,只有图片和链接是默认可拖动的 -->
<div id="box" ondragend="dragEndHandle(event)" draggable="true" onmousedown="onmousedownHandle(event)">
<div class="inner"></div>
</div>
</body>
</html>
<script>
const box = document.getElementById('box');
// 兼容IE和火狐谷歌等的写法
if (window.getComputedStyle) {
// getComputedStyle方法只可读能获取到所有样式,获取到的值带单位而style可读可写但是只能获取到行内样式,获取到的值为数值不带单位
// 参数一:必填,要获取样式的元素,参数二:可选,伪类元素,当不查询伪类元素的时候可以忽略或者传入 null。
var computedStyle = getComputedStyle(box, null);
} else {
var computedStyle = box.currentStyle;//兼容IE的写法
}
const boxMarginTop = parseInt(computedStyle.marginTop)
const boxMarginLeft = parseInt(computedStyle.marginLeft)
// 拖拽结束
function dragEndHandle(e) {
// 原因其实是定位和margin作用会叠加在一起。
// 如果使用的是定位那么还要减去margin否者位置不准,原因是定位其实是准的但是如果元素本身有margin,加上了元素本身的margin这些就会错位
// 所以最终偏移量是:鼠标指针位置相对于当前窗口的 x或y 坐标 - 鼠标相对于触发事件对象的位置 - 拖拽盒子的marginLeft或marginTop
e.target.style.left = e.clientX - x - boxMarginLeft + 'px'
e.target.style.top = e.clientY - y - boxMarginTop + 'px'
}
// 按下事件
function onmousedownHandle(e) {
// e.offsetX 鼠标指针位置相对于触发事件的对象的 x 坐标。
// e.offsetY 鼠标指针位置相对于触发事件的对象的 y 坐标。
// e.clientX 鼠标指针位置相对于当前窗口的 x 坐标
// offsetParent 离元素最近的一个有定位的祖先盒子,如果没有祖先定位盒子则默认位body
// box.offsetTop box这元素到offsetParent的顶部(外边框)的距离
// 获取鼠标相对于触发事件对象的位置
y = e.clientY - box.offsetTop;
x = e.clientX - box.offsetLeft;
}
</script>