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 相关文章推荐
Code:loadScript( )加载js的功能函数
Feb 02 Javascript
CCPry JS类库 代码
Oct 30 Javascript
JS 判断undefined的实现代码
Nov 26 Javascript
jQuery对象和DOM对象使用说明
Jun 25 Javascript
JavaScript入门之事件、cookie、定时等
Oct 21 Javascript
jQuery基于muipicker实现仿ios时间选择
Feb 22 Javascript
Vue自定义指令拖拽功能示例
Feb 17 Javascript
react学习笔记之state以及setState的使用
Dec 07 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
Dec 13 Javascript
JavaScript数据结构与算法之二叉树添加/删除节点操作示例
Mar 01 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 Javascript
Vue点击切换Class变化,实现Active当前样式操作
Jul 17 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 Cookie的一个使用注意点
2008/11/08 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
UI Events 用户界面事件
2012/06/27 Javascript
jquery Moblie入门—hello world的示例代码学习
2013/01/08 Javascript
使用 TypeScript 重新编写的 JavaScript 坦克大战游戏代码
2015/04/07 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
2016/02/21 Javascript
DOM操作和jQuery实现选项移动操作的简单实例
2016/06/07 Javascript
使用jquery/js获取iframe父子级、同级获取元素的方法
2016/08/05 Javascript
Vue之Watcher源码解析(1)
2017/07/19 Javascript
js实现拖拽上传图片功能
2017/08/01 Javascript
vue params、query传参使用详解
2017/09/12 Javascript
在 Angular中 使用 Lodash 的方法
2018/02/11 Javascript
利用d3.js实现蜂巢图表带动画效果
2019/09/03 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
2020/02/09 Javascript
使用Typescript和ES模块发布Node模块的方法
2020/05/25 Javascript
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
2014/04/25 Python
Python类的动态修改的实例方法
2017/03/24 Python
手把手教你python实现SVM算法
2017/12/27 Python
Django基于ORM操作数据库的方法详解
2018/03/27 Python
使用Python编写Prometheus监控的方法
2018/10/15 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
详解appium自动化测试工具(monitor、uiautomatorviewer)
2021/01/27 Python
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
艺龙旅行网酒店预订:国内、港澳台酒店
2018/06/26 全球购物
红色连衣裙精品店:Red Dress Boutique
2018/08/11 全球购物
公司新员工的演讲稿注意事项
2014/01/01 职场文书
顶撞领导检讨书
2014/01/29 职场文书
个人自我评价范文
2014/02/05 职场文书
商务英语专业大学生职业生涯规划书
2014/09/14 职场文书
环境工程专业毕业生求职信
2014/09/30 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
教师专业技术工作总结2015
2015/05/13 职场文书
职工食堂管理制度
2015/08/06 职场文书
交通安全教育主题班会
2015/08/12 职场文书
2016年第二十五次全国助残日活动总结
2016/04/01 职场文书