js原生实现点击拖拽

主要涉及知识点:

元素绑定事件

  • onmousedown
  • onmousemove
  • onmouseup

原生鼠标事件的参数event(获取鼠标位置)

兼容写法:
xxx.onmousemove = (e) => {
var e = e || window.event
}
可以从e中获取clientX和clientY,表示当前鼠标相对于浏览器的坐标

操作span对象的行内样式(属性给个定位)

使用xxx.style.样式 = xxx
由于外联样式不能操作,所以操作行内样式覆盖外联样式
获取外联样式用window的方法 getComputedStyle
getComputedStyle(元素对象, 伪类/null).属性

计算设置span的left和top

为了保证鼠标点击时不乱跳,需要计算鼠标到span边框的距离,再计算span的left/top

注意onmousemove绑定的对象

如果只绑定span,那么当鼠标移动快一点时,鼠标移出了span,会导致拖动失败
只能缓慢拖动才能保证顺利拖动(event更新的时间内,鼠标移动的距离大于span宽高)
所以拖动事件要给到div父元素,才能一直触发

注意计算鼠标和span差值时

要在onmousemove事件外面就计算完成,因为计算使用的clientX/Y再move时也会变化,
如果写在里面,是获取不到鼠标第一次点击时与span的距离的,也会跟着变大变小,
然后span就不会动了
image

代码

html

<body>
    <div>
        <span></span>
    </div>
</body>

css

        * {
            padding: 0;
            margin: 0;
        }
        div {
            height: 1000px;
            width: 100%;
            position: relative;
        }
        span {
            position: absolute;
            display: block;
            height: 100px;
            width: 100px;
            background-color: pink;
            left: 100px;
            top: 100px;
        }

js

    const div = document.querySelector('div')
    const span = document.querySelector('span')
    //获取外联样式给到内敛样式初始化,否则会在后面进行计算时出现Nan导致第一次移动失败
    span.style.left = getComputedStyle(span, null).left
    span.style.top = getComputedStyle(span, null).top
    span.onmousedown = (e) => {
        let offX = parseInt(span.style.left)
        let offY = parseInt(span.style.top)
        let inx = e.clientX - offX //clientX是鼠标距离左侧的距离
        let iny = e.clientY - offY //相减得到鼠标距离span的距离
        div.onmousemove = (e) => {
            let target = e.target
            let x = e.clientX
            let y = e.clientY
            let resX = x - inx
            span.style.left = x - inx + 'px'
            span.style.top = y - iny + 'px'
        }
    }
    div.onmouseup = () => {
        div.onmousemove = null
    }
posted @   一个斯帕纳  阅读(242)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示