javascript实现拖动元素交换位置


Posted in Javascript onNovember 29, 2015

本文实例讲述了javascript实现拖动元素交换位置的代码。分享给大家供大家参考。具体如下:

实现目标:可拖动元素拖动到另外一个元素位置的时候,互相交换位置。

启发来源:最初形式是网上看到的一个拼图小游戏。

运行效果截图如下:

javascript实现拖动元素交换位置

具体代码如下:

代码:

body,ul,li{margin:0;padding:0;}
ul{list-style: none;}
body{font:13px/1.5 Tahoma;}
#box{position:relative;width:435px;height:580px;margin:10px auto;padding: 10px 5px 10px 10px;border: 1px solid #ccc;}
#box li{float:left;width:80px;height:188px;overflow:hidden;background: #ccc;border: 1px solid #999;}
#box li.hig{width:78px;height:186px;overflow:hidden;border:2px dashed blue;}
<ul id="box"></ul>

js代码:

var zIndex = 1;
window.onload = function() {

  var oBox = document.getElementById("box");
  var aLi = oBox.getElementsByTagName("li");
  var aPos = [];
  var aData = [];
  for (i = 0; i < 15; i++)aData.push(i+1);


  //插入结构
  var oFragment = document.createDocumentFragment();
  for (i = 0; i < aData.length; i++) {
    var oLi = document.createElement("li");
    oFragment.appendChild(oLi)
  }
  oBox.appendChild(oFragment);

  //布局转换
  for (i = 0; i < aLi.length; i++) {
    aLi[i].index = i;
    aLi[i].style.top = aLi[i].offsetTop + "px";
    aLi[i].style.left = aLi[i].offsetLeft + "px";
    aLi[i].style.margin = "0 5px 5px 0";
    aPos.push({
      "left": aLi[i].offsetLeft,
      "top": aLi[i].offsetTop
    })
  }
  for (i = 0; i < aLi.length; i++) {
    aLi[i].style.position = "absolute";    
    drag(aLi[i])
  }

  //拖拽函数
  function drag(obj, handle) {
    var handle = handle || obj;
    handle.style.cursor = "move";
    handle.onmousedown = function(event) {
      var event = event || window.event;
      var disX = event.clientX - this.offsetLeft;
      var disY = event.clientY - this.offsetTop;
      var oNear = null;
      obj.style.zIndex = zIndex++;
      document.onmousemove = function(event) {
        var event = event || window.event;
        var iL = event.clientX - disX;
        var iT = event.clientY - disY;
        var maxL = obj.parentNode.clientWidth - obj.offsetWidth;
        var maxT = obj.parentNode.clientHeight - obj.offsetHeight;

        iL < 0 && (iL = 0);
        iT < 0 && (iT = 0);
        iL > maxL && (iL = maxL);
        iT > maxT && (iT = maxT);
        obj.style.left = iL + "px";
        obj.style.top = iT + "px";

        for (i = 0; i < aLi.length; i++) aLi[i].className = "";

        oNear = findNearest(obj);

        oNear && (oNear.className = "hig");

        return false
      };
      document.onmouseup = function() {
        document.onmousemove = null;
        document.onmouseup = null;
        if (oNear) {
          var tIndex = obj.index;
          obj.index = oNear.index;
          oNear.index = tIndex;
          startMove(obj, aPos[obj.index]);
          startMove(oNear, aPos[oNear.index], function() {
            
          });
          oNear.className = "";
        } else {
          startMove(obj, aPos[obj.index])
        }
        handle.releaseCapture && handle.releaseCapture()
      };
      this.setCapture && this.setCapture();
      return false
    }
  }

  //找出相遇点中最近的元素
  function findNearest(obj) {
    var filterLi = [];
    var aDistance = [];

    for (i = 0; i < aLi.length; i++) aLi[i] != obj && (isButt(obj, aLi[i]) && (aDistance.push(getDistance(obj, aLi[i])), filterLi.push(aLi[i])));

    var minNum = Number.MAX_VALUE;
    var minLi = null;

    for (i = 0; i < aDistance.length; i++) aDistance[i] < minNum && (minNum = aDistance[i], minLi = filterLi[i]);

    return minLi
  }



};
//求两点之间的距离
function getDistance(obj1, obj2) {
  var a = (obj1.offsetLeft + obj1.offsetWidth / 2) - (obj2.offsetLeft + obj2.offsetWidth / 2);
  var b = (obj1.offsetTop + obj1.offsetHeight / 2) - (obj2.offsetTop + obj2.offsetHeight / 2);
  return Math.sqrt(a * a + b * b)
}

//碰撞检测
function isButt(obj1, obj2) {
  var l1 = obj1.offsetLeft;
  var t1 = obj1.offsetTop;
  var r1 = obj1.offsetLeft + obj1.offsetWidth;
  var b1 = obj1.offsetTop + obj1.offsetHeight;

  var l2 = obj2.offsetLeft;
  var t2 = obj2.offsetTop;
  var r2 = obj2.offsetLeft + obj2.offsetWidth;
  var b2 = obj2.offsetTop + obj2.offsetHeight;

  return !(r1 < l2 || b1 < t2 || r2 < l1 || b2 < t1)
}

//获取最终样式
function getStyle(obj, attr) {
  return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr])
}

//运动框架
function startMove(obj, pos, onEnd) {
  clearInterval(obj.timer);
  obj.timer = setInterval(function() {
    doMove(obj, pos, onEnd)
  }, 30)
}

function doMove(obj, pos, onEnd) {
  var iCurL = getStyle(obj, "left");
  var iCurT = getStyle(obj, "top");
  var iSpeedL = (pos.left - iCurL) / 5;
  var iSpeedT = (pos.top - iCurT) / 5;
  iSpeedL = iSpeedL > 0 ? Math.ceil(iSpeedL) : Math.floor(iSpeedL);
  iSpeedT = iSpeedT > 0 ? Math.ceil(iSpeedT) : Math.floor(iSpeedT);
  if (pos.left == iCurL && pos.top == iCurT) {
    clearInterval(obj.timer);
    onEnd && onEnd()
  } else {
    obj.style.left = iCurL + iSpeedL + "px";
    obj.style.top = iCurT + iSpeedT + "px";
  }
}

 

以上就是javascript实现拖动元素交换位置的全部代码,希望对大家的学习有所帮助。

Javascript 相关文章推荐
实现png图片和png背景透明(支持多浏览器)的方法
Sep 08 Javascript
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
Jan 12 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
Apr 07 Javascript
JS删除数组元素的函数介绍
Mar 27 Javascript
AngularJS进行性能调优的7个建议
Dec 28 Javascript
JavaScript修改作用域外变量的方法
Mar 25 Javascript
jQuery ui autocomplete选择列表被Bootstrap模态窗遮挡的完美解决方法
Sep 23 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
Oct 05 Javascript
使用D3.js创建物流地图的示例代码
Jan 27 Javascript
layui表格内容溢出的解决方法
Sep 06 Javascript
layui表单提交到后台自动封装到实体类的方法
Sep 12 Javascript
three.js欧拉角和四元数的使用方法
Jul 26 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
Nov 29 #Javascript
通用javascript代码判断版本号是否在版本范围之间
Nov 29 #Javascript
jQuery如何使用自动触发事件trigger
Nov 29 #Javascript
js性能优化技巧
Nov 29 #Javascript
javascript实现C语言经典程序题
Nov 29 #Javascript
JavaScript学习小结(7)之JS RegExp
Nov 29 #Javascript
整理Javascript基础入门学习笔记
Nov 29 #Javascript
You might like
深入探讨:PHP使用数据库永久连接方式操作MySQL的是与非
2013/06/05 PHP
PHP实现设计模式中的抽象工厂模式详解
2014/10/11 PHP
thinkphp中空模板与空模块的用法实例
2014/11/26 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
laravel5环境隐藏index.php后缀(apache)的方法
2019/10/12 PHP
判断控件是否已加载完成的代码
2010/02/24 Javascript
将Datatable转化成json发送前台实现思路
2013/09/06 Javascript
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
JS实现点击按钮自动增加一个单元格的方法
2015/03/09 Javascript
JS实现简单的图书馆享元模式实例
2015/06/30 Javascript
全面解析Bootstrap中transition、affix的使用方法
2016/05/30 Javascript
详解Vue使用 vue-cli 搭建项目
2017/04/20 Javascript
使用Math.max,Math.min获取数组中的最值实例
2017/04/25 Javascript
常见的浏览器Hack技巧整理
2017/06/29 Javascript
利用JS制作万年历的方法
2017/08/16 Javascript
webpack项目调试以及独立打包配置文件的方法
2018/02/28 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
Layui table field初始化加载时进行隐藏的方法
2019/09/19 Javascript
Linux系统(CentOS)下python2.7.10安装
2018/09/26 Python
Django框架验证码用法实例分析
2019/05/10 Python
python django下载大的csv文件实现方法分析
2019/07/19 Python
Python3标准库之functools管理函数的工具详解
2020/02/27 Python
Python稀疏矩阵及参数保存代码实现
2020/04/18 Python
Python入门基础之数字字符串与列表
2021/02/01 Python
24个canvas基础知识小结
2014/12/17 HTML / CSS
浅析HTML5 meta viewport参数
2020/10/28 HTML / CSS
女儿十岁生日答谢词
2014/01/27 职场文书
互联网创业计划书写作技巧攻略
2014/03/23 职场文书
买房委托公证书
2014/04/08 职场文书
高中生逃课检讨书
2014/10/10 职场文书
小学生一年级(书信作文)
2019/08/13 职场文书
导游词之镜泊湖
2019/12/09 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server
SQL写法--行行比较
2021/08/23 SQL Server