js实现鼠标拖拽效果

初步


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        *{
      
            margin: 0;
            padding: 0;
            user-select: none;
        }
        #box{
      
            width: 200px;
            height: 200px;
            background-color: orangered;
            position: absolute;
        }
        h3{
      
            height: 30px;
            line-height: 30px;
            text-align: center;
            color: #fff;
            background-color: coral;
        }
    style>
head>
<body>
    <div id="box">
        <h3 id="title">蜘蛛侠h3>
    div>
    
    <script>
        let box=document.getElementById('box');
        let title=document.getElementById('title');
        //利用js实现盒子上下左右居中
        let left=(document.documentElement.clientWidth-box.offsetWidth)/2;
        let topp=(document.documentElement.clientHeight-box.offsetHeight)/2;
        box.style.left=left+'px';
        box.style.top=topp+'px';

        //实现拖拽的逻辑
        //当用户按下鼠标的时候开始给当前title绑定鼠标移动事件,当用户抬起鼠标的时候,移除title的移动事件
        title.onmousedown=function(e){
      
            // 记录一下鼠标按下时的盒子的初始left值和鼠标的e.clientX
            this.oldClientX=e.clientX;//记录初始的鼠标的clientX值
            this.oldClientY=e.clientY;//记录初始的鼠标的clientY值
            
            this.oldLeft=parseFloat(box.style.left);//记录初始的盒子的left值
            this.oldTop=parseFloat(box.style.top);//记录初始的盒子的top值

            this.onmousemove=move;//给title绑定鼠标移动事件


        }
        function move(e){
      
            //获取当前鼠标的最新的clientX/Y,然后减去初始的clientX/Y,这就是光标移动的距离,也是盒子需要移动的距离
            //盒子最新的位置等于盒子主要移动的距离加上初始的距离
            let curLeft=e.clientX-this.oldClientX + this.oldLeft+'px';
            let curTop=e.clientY-this.oldClientY + this.oldTop+'px';
            box.style.left=curLeft;
            box.style.top=curTop;
        }
        title.onmouseup=function(){
      
            title.onmousemove=null;
        }
    script>
body>
html>

优化

上面的实现方式有缺陷:盒子每移动一次就需要dom回流重绘一次,消耗性能,这时候如果鼠标移动的太快,那浏览器计算盒子的位置的速度就跟不上鼠标移动的速度,所以鼠标就跑出了盒子之外,这时候在盒子外边抬起鼠标,并没有触发title的onmouseup事件,这时候title的onmousemove事件并没有被移除,所以鼠标再次进入的时候还是有鼠标移动事件。

		let box=document.getElementById('box');
        let title=document.getElementById('title');

        let left=(document.documentElement.clientWidth-box.offsetWidth)/2;
        let topp=(document.documentElement.clientHeight-box.offsetHeight)/2;
        box.style.left=left+'px';
        box.style.top=topp+'px';

        title.onmousedown=function(e){
     
            this.oldClientX=e.clientX;
            this.oldClientY=e.clientY;
            
            this.oldLeft=parseFloat(box.style.left);
            this.oldTop=parseFloat(box.style.top);

            //把当前的onmousemove绑定给document,这样不管你在哪里移动,通过冒泡机制都会触发document的onmousemove事件
            document.onmousemove=move.bind(this);
            // document.οnmοusemοve=function(e){
     
            //     //this-->document
            //     move.call(title,e);//不是window执行的,需要获取事件对象e
            // }
        }
        function move(e){
     
            let curLeft=e.clientX-this.oldClientX + this.oldLeft+'px';
            let curTop=e.clientY-this.oldClientY + this.oldTop+'px';
            box.style.left=curLeft;
            box.style.top=curTop;
        }
        //通过冒泡机制,不管在哪里执行鼠标抬起都会触发document的onmouseup事件
        document.onmouseup=function(){
     
            document.onmousemove=null;
        }

你可能感兴趣的:(JavaScript,javascript,事件冒泡)