明天早上看到一个前端面试的题目《利用原生 js 实现元素拖拽》,忽然就想到了当初学到 offset
clent
scroll
这地位三大家做的一个案例“实现拖拽盒子”
于是明天就又拿进去写了一下,并且记录成博客,一方面加深记忆,另一方面也再相熟相熟原生 js(集体很喜爱很喜爱原生 js)
首先,做一个我的项目之前(不论我的项目大小)都该当先列举一下业务逻辑和思路,简而言之就是 工作纲要:
- 实现页面 DOM 构建,并将必备款式筹备结束
- 鼠标在盒子上按下,并挪动时该当让盒子追随鼠标的挪动而挪动
- 鼠标松开时勾销鼠标按下及其后续事件
接下来咱们一步一步的执行:
css 局部:
* {
margin: 0;
padding: 0;
}
.box {
position: relative; /* 定位用相对 absolute 也能够 */
width: 500px;
height: 300px;
background-color: #5f5f5f;
}
html 局部:
<div id="box" class="box"></div>
js 局部:
const box = document.getElementById('box')
box.onmousedown = function (e) {
// 解决 IE 浏览器事件兼容性问题
e = e || e.event
// 获取鼠标按下时此时鼠标位于 box 中的偏移地位 startX 和 startY
let startX = e.offsetX,
startY = e.offsetY
// 在 box 上监听鼠标挪动的事件
this.onmousemove = function (e) {
// 解决 IE 浏览器事件兼容性问题
e = e || e.event
// 计算 box 的 left 和 top 属性(box 必须通过定位脱离文档流)// 此时 box 的程度偏移地位就是:this.offsetLeft
// 此时鼠标在盒子中的程度偏移地位是:e.offsetX
// 鼠标按下霎时获取到的鼠标偏移地位是:startX
// 记得最初肯定要加上单位,不然不会产生偏移
this.style.left = this.offsetLeft + (e.offsetX - startX) + 'px'
this.style.top = this.offsetTop + (e.offsetY - startY) + 'px'
}
}
// 在盒子上鼠标左键抬起时监听的事件,将事件赋值为 null 与 removeEventListener 一样
box.onmouseup = function () {this.onmousemove = null}
其实鼠标拖拽一个元素在页面上挪动的原理就是:
鼠标产生挪动时,让盒子也挪动雷同的间隔(X 轴和 Y 轴),也就是说鼠标与盒子某一个点是绝对静止的,等价代换之后咱们就能够晓得,其实就是 盒子的 left 和 top 值 = 鼠标挪动的间隔 + 盒子本来的偏移间隔
而鼠标挪动的间隔 = 以后(实时)鼠标在盒子中的 offsetX - 鼠标最后点击那一瞬间的 offsetX(上文中我将其存入了变量 startX 中)