1. 程式人生 > >用javascript實現拖拽帶來的種種問題(1)

用javascript實現拖拽帶來的種種問題(1)

round head 出發 mark mov 點擊事件 pan func 屬性

第一篇,先水一下,用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實現拖拽帶來的種種問題(1)