js拖拽自動排列

上一次寫了拖拽,其實主要仍是想實現拖拽以後實現自動排列,跟手機屏幕那樣移動圖標能夠自動排列,先看效果:html

很常見的一個效果,先說一下思路:數組

每個元素都是絕對定位,初始化的時候是經過js去排列。bash

拖拽使用的方法跟上一篇文章如出一轍。ui

定義了一個數組,每一個元素的字段:spa

{el: elArr[i], sort: i, index: i}code

el是這個元素,用於排列,也就是改變top和left,sort是元素排列的位置,index是當前元素的index,不會改變。cdn

拖拽的時候,當鼠標點擊選中當前的元素的時候,這個元素移動,當移動到另外一個元素一半的時候,至關於要替換這個元素,我是以這樣一個方法判斷移動到哪個位置:htm

let moveIndex = Math.round(x / 125) + Math.round(y / 125) * 5;排序

我元素的寬度和距離的寬度和是125,因此移動距離超過一半就四捨五入算加1,列方向也是同樣,超過1那麼元素就是要加一行的個數。ip

我定義了一個當前的index,若是移動到的index不等於初始化的index,那麼就是要發生移動,當從大移動到小,在這個範圍內的,全部排序都要加1,其餘不變,若是從小移動到大,這個範圍內排序都要減1,其餘不變。而後當前的排序替換那個。還要判斷,若是移動計算出來的index小於0就等於0,大於當前最大值就等於當前最大值。

選中當前要改變index,置於最上方,移動用的是transition使得緩和的變換,可是移動當前要使transition爲0秒,不然延遲會脫離當前元素。

仍是上代碼,運行以後看看代碼就很清楚了:

<!DOCTYPE html>

<html>

<head>

    <title></title>

    <style>

        *{

            padding:0;

            margin:0;

        }

        html, body{

            width:100%;

            height:100%;

        }

        .wrap{

            position: relative;

            width: 600px;

            height: 600px;

            margin: 100px auto;

            border: solid 1px red;

        }

        .wrap div{

            position:absolute;

            z-index: 1;

            width:100px;

            height:100px;

            background: red;

            transition: all .5s;

        }

    </style>

</head>

<body>



<div class="wrap" id="elWrap">

    <div>1</div>

    <div>2</div>

    <div>3</div>

    <div>4</div>

    <div>5</div>

    <div>6</div>

    <div>7</div>

    <div>8</div>

    <div>9</div>

    <div>10</div>

</div>



<script>

  let index = 0;

    let elArr = document.getElementById('elWrap').children;

    let elList =[];

    //構造一個數組

    for(let i = 0;i < elArr.length;i++){

     elList.push({el: elArr[i], sort: i, index: i});

     elList[i].onclick = addEvent(elList[i]);

    }

    moveItem(elList);

    

    function addEvent(item) {

     item.el.addEventListener('mousedown',(e) => {

      item.el.style.zIndex = 2;

      item.el.style.transition = 'all 0s';

        let startX = e.pageX,

        startY = e.pageY,

        left = item.el.offsetLeft,

        top = item.el.offsetTop;

        

        let moveFun = (e) => {

         let X = e.pageX - startX + left;

         let Y = e.pageY - startY + top;

         item.el.style.left = `${X}px`;

         item.el.style.top = `${Y}px`;

         reRange(item, X, Y);

        };

        

        document.addEventListener('mousemove',moveFun);

      item.el.addEventListener('mouseup',() => {

          document.removeEventListener('mousemove',moveFun);

       item.el.style.zIndex = 1;

       item.el.style.transition = 'all .5s';

       moveItem(elList);

        });

      });

    }

    

    function reRange(item, x, y) {

     let moveIndex = Math.round(x / 125) + Math.round(y / 125) * 5;

        moveIndex = moveIndex < 0 ? 0 : moveIndex;

        moveIndex = moveIndex > elList.length - 1 ? elList.length - 1 : moveIndex;

        

     if(moveIndex != index){

      index = moveIndex;

      let currentSort = item.sort;

      for(let i = 0;i < elList.length;i++){

       if(currentSort < moveIndex){

        if(elList[i].sort > currentSort && elList[i].sort <= moveIndex){

         elList[i].sort -= 1;

        };

       }else if(currentSort > moveIndex){

        if(elList[i].sort < currentSort && elList[i].sort >= moveIndex){

         elList[i].sort += 1;

        };

       }

      };

      elList[item.index].sort = moveIndex;

      moveItem(elList);

     }

    }

    //排列

    function moveItem(elList) {

        for(let i = 0;i < elList.length;i++){

            elList[i].el.style.left = elList[i].sort % 5 * 125 + 'px';

            elList[i].el.style.top = parseInt(elList[i].sort / 5) * 125 + 'px';

        }

    }

</script>

</body>

</html>

複製代碼

相關文章
相關標籤/搜索