通過拖動實現調整元素之間位置程式碼例項

antzone發表於2017-04-13

分享一段程式碼例項,它實現了通過拖動來調整元素之間位置的功能。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
* {
  margin: 0;
  padding: 0;
  list-style: none;
}
#ul1 {
  position: relative;
  width: 688px;
  margin: 30px auto;
}
#ul1 li {
  float: left;
  width: 50px;
  height: 50px;
  line-height: 150px;
  text-align: center;
  font-size: 30px;
  border: 1px solid #000;
  background: #ccc;
  margin: 60px;
}
</style>
<script>
function move(obj, json, optional) {
  optional = optional || {};
  optional.time = optional.time || 500;
  optional.type = optional.type || 'ease-out';
  optional.fn = optional.fn || null;
 
  var start = {};
  var dis = {};
 
  for (var key in json) {
    start[key] = parseFloat(getStyle(obj, key));
    dis[key] = json[key] - start[key];
  }
 
  var count = Math.round(optional.time / 30);
  var n = 0;
 
  clearInterval(obj.timer);
  obj.timer = setInterval(function() {
    n++;
    for (var key in json) {
      switch (optional.type) {
        case 'linear':
          var a = n / count;
          break;
        case 'ease-in':
          var a = n / count;
          a = a * a * a;
          break;
        case 'ease-out':
          var a = 1 - n / count;
          var a = 1 - a * a * a;
          break;
      }
      var cur = start[key] + dis[key] * a;
      if (key == 'opacity') {
        obj.style.opacity = cur;
        obj.style.filter = 'alpha(opacity=' + cur * 100 + ')';
      } else {
        obj.style[key] = cur + 'px';
      }
    }
 
    if (n == count) {
      clearInterval(obj.timer);
 
      optional.fn && optional.fn();
    }
  }, 30);
}
 
function getStyle(obj, name) {
  return obj.currentStyle ? obj.currentStyle[name] : getComputedStyle(obj, false)[name];
}
 
window.onload = function() {
  var oUl = document.getElementById("ul1");
  var aLi = oUl.children;
  var zIndex = 1;
  //1 佈局轉換
  var aPos = [];
  for (var i = 0; i < aLi.length; i++) {
    aPos[i] = {
      left: aLi[i].offsetLeft,
      top: aLi[i].offsetTop
    };
    aLi[i].style.left = aPos[i].left + 'px';
    aLi[i].style.top = aPos[i].top + 'px';
  }
 
  for (var i = 0; i < aLi.length; i++) {
    aLi[i].style.position = 'absolute'
    aLi[i].style.margin = 0;
    drag(aLi[i])
    aLi[i].innerHTML = i;
    aLi[i].index = i;
  }
 
  //拖拽
  function drag(obj) {
    obj.onmousedown = function(e) {
      obj.style.zIndex = zIndex++;
      var oEvent = e || event;
      var disX = oEvent.clientX - obj.offsetLeft;
      var disY = oEvent.clientY - obj.offsetTop;
 
      document.onmousemove = function(e) {
        var oEvent = e || event;
        obj.style.left = oEvent.clientX - disX + 'px';
        obj.style.top = oEvent.clientY - disY + 'px';
 
        var oNear = findMin(obj);
        //console.log(oNear)
        if (oNear && oNear != obj) {
 
          n = obj.index //
          m = oNear.index //
 
          if (n < m) {
            for (var i = 0; i < aLi.length; i++) {
              if (aLi[i].index >= n + 1 && aLi[i].index <= m) {
                aLi[i].index--;
                move(aLi[i], aPos[aLi[i].index])
              }
            }
          } else {
            for (var i = 0; i < aLi.length; i++) {
              if (aLi[i].index >= m && aLi[i].index <= n - 1) {
                aLi[i].index++;
                move(aLi[i], aPos[aLi[i].index])
              }
            }
          }
          obj.index = m;
        } //
      }
      document.onmouseup = function(e) {
        document.onmouseup = null;
        document.onmousemove = null
        obj.releaseCapture && obj.releaseCapture()
        move(obj, aPos[obj.index])
 
      }
      obj.setCapture && obj.setCapture()
      return false;
    }
  }
 
  //找最近的距離
  function findMin(obj) {
    var iMin = 9999999;
    var iMInIndex = -1;
    for (var i = 0; i < aLi.length; i++) {
      if (collTest(obj, aLi[i])) {
        var dis = getDis(obj, aLi[i]) //算距離
        if (iMin > dis) { //比較
          iMin = dis;
          iMInIndex = i;
        }
      }
    }
    return aLi[iMInIndex];
  }
  //算距離
  function getDis(obj1, obj2) {
    var x1 = obj1.offsetLeft + obj1.offsetWidth / 2;
    var y1 = obj1.offsetTop + obj1.offsetHeight / 2
 
    var x2 = aPos[obj2.index].left + obj2.offsetWidth / 2;
    var y2 = aPos[obj2.index].top + obj2.offsetHeight / 2
 
    var a = x1 - x2;
    var b = y1 - y2;
    return Math.sqrt(a * a + b * b)
 
  }
  //碰撞檢測
  function collTest(obj1, obj2) {
    var l1 = obj1.offsetLeft;
    var t1 = obj1.offsetTop;
    var r1 = obj1.offsetLeft + obj1.offsetWidth;
    var b1 = obj1.offsetTop + obj1.offsetHeight;
 
    var l2 = aPos[obj2.index].left;
    var t2 = aPos[obj2.index].top;
    var r2 = aPos[obj2.index].left + obj2.offsetWidth;
    var b2 = aPos[obj2.index].top + obj2.offsetHeight;
 
    //判斷沒撞上的時候
    if (l1 > r2 || t1 > b2 || r1 < l2 || b1 < t2) {
      return false
    } else {
      return true
    }
  }
};
</script>
</head>
<body>
  <ul id="ul1">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>
</html>

相關文章