用javascript实现拖拽带来的种种问题

Posted tarosun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用javascript实现拖拽带来的种种问题相关的知识,希望对你有一定的参考价值。

第一篇,先水一下,用javascript实现简单的拖拽。主要还是想通过demo的形式总结一下各种event对象属性。

首先先看一下,这个demo最终实现的效果:

技术分享图片

主要涉及的属性有: MouseEvent.clientXMouseEvent.clientYhtmlElement.offsetLeftHTMLElement.offsetTop

好,先解决这些属性是什么!

MouseEvent.clientX 和clienY

代表触发事件时鼠标在视口中的的水平距离和垂直距离

HTMLElement.offsetLeft 和offsetTop

元素从border开始到父元素的内border结束

千言万语不如来一张图说的明白:
技术分享图片

好,概念解决了。来分析一下该怎么实现这个效果。

基础代码:

    *{
        padding: 0;
        margin: 0;
    }
    #box{
        height: 100px;
        width: 100px;
        position: absolute;
        top: 50px;
        left: 50px;
        background: red;
    }
    <div id="box"></div>
    var box = document.getElementById("box");
  1. 首先有一个点击事件。(onmousedown)
    • 当触发点击事件是,我们可以根据clientXclientY获得鼠标在视口的位置

代码如下:


        //按下触发的事件
    box.onmousedown = function(e) {
        //点击元素视口左边的距离,适口右边的距离
        var m_x = e.clientX;          
        var m_y = e.clientY;
    }
  1. 接着是鼠标的移动事件(onmouseover)
    • 鼠标移动事件结束后,同样也可以获得结束后鼠标在视口的位置。因为是在鼠标点击后立即出发移动事件。所以移动事件需要写在点击事件中
      代码如下:

      document.onmousemove = function(e){
      //移动的距离,左边到适口的距离,和上边到适口的距离
      var x = e.clientX;
      var y = e.clientY;
      }
  2. 通过前两步得到的数据,可以计算出整个拖拽事件运动的距离。通过这个距离就可以设置元素最后的位置
    代码如下:

    var resultX = x-m_x;
    var resultY = y-m_y;
    box.style.left =resultX+"px";//元素最后的水平位置
    box.style.top =resultY+"px";//元素最后的垂直位置
  3. 最后是鼠标抬起事件(onmouseup)
    代码如下:

    document.onmouseup = function(){
        document.onmousemove = null;
    }

    先写到这,来试一下写的代码,效果如下:
    技术分享图片

这里出现了问题,第一次拖拽效果,没问题。但第二次当鼠标按下再次移动时,元素回到了视口的最左上角,即视口的(0,0)点。而我希望的是当我第二次点击拖拽时,它能在第二次点击位置开始移动。那为什么会这样呢,原因是,没有保存元素移动后的位置。所以现在需要两个值来记录元素左上顶点的位置。这时就需要offsetLeftoffsetTop来获取。
代码如下:

    var positionx = this.offsetLeft;
    var positiony = this.offsetTop;
    box.style.left =positionx+ resultX+"px";
    box.style.top =positiony+ resultY+"px";

这样就解决了第二次移动时元素再也不会跑到视口左上角的问题了

整个代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    *{
        padding: 0;
        margin: 0;
    }
    #box{
        height: 100px;
        width: 100px;
        position: absolute;
        top: 50px;
        left: 50px;
        background: red;
    }
    </style>
</head>
<body>
    <div id="box"></div>
    <script>
        var box = document.getElementById("box");
        //按下触发的时间

        box.onmousedown = function(e) {
            //点击元素视口左边的距离,适口右边的距离
            var m_x = e.clientX;          
            var m_y = e.clientY;

            //没有设置顶点位置,我需要每一次都保留元素顶点的位置,可以用offsetleft,offsettop
            var positionx = this.offsetLeft;
            var positiony = this.offsetTop;


            document.onmousemove = function(e){
                //移动的距离,左边到适口的距离,和上边到适口的距离
                var x = e.clientX;
                var y = e.clientY;
                

                var resultX = x-m_x;
                var resultY = y-m_y;

                
                box.style.left =positionx+ resultX+"px";
                box.style.top =positiony+ resultY+"px";

            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
        }
    </script>
</body>
</html>

写在最后

本想写个简单的案例试试手,结果却发现,想和做是两回事!还需要多多练习啊







以上是关于用javascript实现拖拽带来的种种问题的主要内容,如果未能解决你的问题,请参考以下文章

javascript动画系列第一篇——模拟拖拽

JS倒计时两种种实现方式 很不错

JavaScript:js实现拖拽移动,删除后自动排列

用HTML5实现Selenium Java拖拽功能

JavaScript实现拖拽元素对齐到网格(每次移动固定距离)

JavaScript实现网页元素的拖拽效果