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 相关文章推荐
基于jQuery的输入框无值自动显示指定数据的实现代码
Jan 24 Javascript
查看图片(前进后退)功能实现js代码
Apr 24 Javascript
Javascript表格翻页效果的具体实现
Oct 05 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
js实现ifram取父窗口URL地址的方法
Feb 09 Javascript
JS实现支持Ajax验证的表单插件
Mar 24 Javascript
详谈for循环里面的break和continue语句
Jul 20 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
Jan 21 Javascript
浅析Vue 生命周期
Jun 21 Javascript
详解vue的数据劫持以及操作数组的坑
Apr 18 Javascript
vue里的data要用return返回的原因浅析
May 28 Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
Oct 08 jQuery
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
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
php获取textarea的值并处理回车换行的方法
2014/10/20 PHP
js css后面所带参数含义介绍
2013/08/18 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
javascript实现浏览器窗口传递参数的方法
2014/09/03 Javascript
jquery实现标签上移、下移、置顶
2015/04/26 Javascript
jQuery取得iframe中元素的常用方法详解
2016/01/14 Javascript
nodejs修复ipa处理过的png图片
2016/02/17 NodeJs
XML、HTML、CSS与JS的区别整理
2016/02/18 Javascript
基于React.js实现原生js拖拽效果引发的思考
2016/03/30 Javascript
javaScript中的原型解析【推荐】
2016/05/05 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
2016/09/08 Javascript
JavaScript定义数组的三种方法(new Array(),new Array('x','y')
2016/10/04 Javascript
js继承实现方法详解
2016/12/16 Javascript
微信小程序 登录实例详解
2017/01/16 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
2019/01/29 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
python使用内存zipfile对象在内存中打包文件示例
2014/04/30 Python
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
python标准算法实现数组全排列的方法
2015/03/17 Python
Python批量提取PDF文件中文本的脚本
2018/03/14 Python
在cmder下安装ipython以及环境的搭建
2018/10/19 Python
python框架Django实战商城项目之工程搭建过程图文详解
2020/03/09 Python
Python reversed函数及使用方法解析
2020/03/17 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
html5写一个BUI折叠菜单插件的实现方法
2019/09/11 HTML / CSS
销售经理工作职责范文
2013/12/03 职场文书
成品库仓管员岗位职责
2014/04/06 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
2015年英语教学工作总结
2015/05/25 职场文书
被告代理词范文
2015/05/25 职场文书
高温慰问简报
2015/07/21 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS