mousedown、mousemove、mouseup实现一个可拖拽的div

可拖拽的div

前言:前端开发当中不单单是简单的页面布局,很多的事件也应用在其中,比如一个窗口实现在整个页面的拖动的需求。

明确步骤
(1)对div设置position:absolute;属性并设置top:100px;left:100px;
(2)监听div的mousedown事件
(3)监听整个页面document的mousemove事件
(4)监听整个页面document的mouseup事件
(5)通过监听事件来拿到clientX和clientY,计算出和按下鼠标位置的xy计算差值,然后赋值给left和top

注意的点,看似简单有很多小细节

mousedown,mousedown,mouseup分别监听的对象是谁?

首先我们要知道这几个都是监听的鼠标的位置,只不过是对象是谁罢了

mousedown监听的是div我们要拖动的对象,是为了拿到鼠标在div上的初始位置
mousemove监听是整个页面的事件,为什么不是div,因为在移动的时候鼠标速度过快的话,直接就很快速的移出div那就监听不到了,也就是div一下就停下来了,不能跟着移动了,(我管这种现象加到失针的行列中)
mouseup和上述一样

拿到的是带有px的值还是数字?刚开始获取style.left和top是否有值?(是undefined还是什么)

drap是id名称

		let drap = document.getElementById("drap")
		let x = e.clientX
        let y = e.clientY
        let deltaX = x - position[0]
        let deltaY = y - position[1]
        let left = drap.style.left 
        let top = drap.style.top 
        drap.style.left = left + deltaX 
        drap.style.top = top + deltaY 

这是一股脑下来的结果,我们e.clientX得到的是一个数字,而且刚开始的时候style.left 拿到的是undefined,
看代码

第一个明显错误
		drap.style.left = left + deltaX 
        drap.style.top = top + deltaY 

这个是什么?数字,我们left和top是什么有单位的,px, 所以要加上

		drap.style.left = left + deltaX +‘px’
        drap.style.top = top + deltaY +‘px’
第二个错误(我也是查了半天,调试一点一点看是否有值)
	drap.style.left 

刚开始的时候获取的是undefined,因为这段代码是监听事件是对于整个页面,也就是dom元素没有显示出来,第一次已经监,但是此时dom元素并没有渲染出来,要进行获运算符来赋值一个初始值

还要注意的是我们移动过程中,dom渲染好了之后获取到style.left,是带有px的不能直接用来数学运算 parseInt()要进行一个剔除抓换成纯数字

		let left = parseInt(drap.style.left || 100)
        let top = parseInt(drap.style.top || 100)
第三个错误

可能有人会没有意识到,就是div能拖动的前提是脱离文档流,postion:absolute

需要注意的点已经说完了,直接上代码,我直接写在了一个HTML中,没有分开说封一个组件,大概的原理讲清楚即可

<!DOCTYPE html>
<html lang="">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>可拖动的div</title>
    <style>
        #drap {
            width: 100px;
            height: 100px;
            border: 1px solid red;
            position: absolute;
            top: 100px;
            left: 100px;
        }
    </style>
</head>

<body>
    <div id="drap"></div>
</body>
<script>
    var dragging = false
    var position = null
    let drap = document.getElementById("drap")
    drap.addEventListener("mousedown", function (e) {
        dragging = true
        position = [e.clientX, e.clientY]
    })
    document.addEventListener('mousemove', function (e) {
        if (dragging === false) {
            return
        }
        let x = e.clientX
        let y = e.clientY
        let deltaX = x - position[0]
        let deltaY = y - position[1]
        let left = parseInt(drap.style.left || 100)
        let top = parseInt(drap.style.top || 100)
        drap.style.left = left + deltaX + 'px'
        drap.style.top = top + deltaY + 'px'
        position = [x, y]
    })
    document.addEventListener('mouseup', function (e) {
        dragging = false
    })
</script>

</html>

当然了如果为了样式好一点可以加一些拖动的样式,比如:hover{
cursor: move;
}

在这里插入图片描述

一点一点积累!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值