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插件之打造自定义的select标签
Nov 30 Javascript
ExtJS下书写动态生成的xml(兼容火狐)
Apr 02 Javascript
一个js控制的导航菜单实例代码
Dec 03 Javascript
JS简单操作select和dropdownlist实例
Nov 26 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
Jan 02 Javascript
JavaScript中用toString()方法返回时间为字符串
Jun 12 Javascript
基于bootstrap3和jquery的分页插件
Jul 31 Javascript
延时加载JavaScript代码提高速度
Dec 27 Javascript
switch语句的妙用(必看篇)
Oct 03 Javascript
ZeroClipboard.js使用一个flash复制多个文本框
Jun 19 Javascript
关于JS与jQuery中的文档加载问题
Aug 22 jQuery
VUE和Antv G6实现在线拓扑图编辑操作
Oct 28 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 读取Postgresql中的数组
2013/04/14 PHP
PHP容易忘记的知识点分享
2013/04/30 PHP
ThinkPHP自动完成中使用函数与回调方法实例
2014/11/29 PHP
利用php + Laravel如何实现部署自动化详解
2017/10/11 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
2017/10/19 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
jquery实现控制表格行高亮实例
2013/06/05 Javascript
轻松创建nodejs服务器(5):事件处理程序
2014/12/18 NodeJs
javascript面向对象之访问对象属性的两种方式分析
2015/01/13 Javascript
JS+CSS简单树形菜单实现方法
2015/09/12 Javascript
JSON遍历方式实例总结
2015/12/07 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
2016/12/28 Javascript
Vue键盘事件用法总结
2017/04/18 Javascript
基于JS实现web端录音与播放功能
2019/04/17 Javascript
Vue安装浏览器开发工具的步骤详解
2019/05/12 Javascript
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
[04:23]DOTA2上海特锦赛小组赛第一日 TOP10精彩集锦
2016/02/27 DOTA
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
使用Python操作excel文件的实例代码
2017/10/15 Python
Python实现简单求解给定整数的质因数算法示例
2018/03/25 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
Python Pandas 获取列匹配特定值的行的索引问题
2019/07/01 Python
在python中将list分段并保存为array类型的方法
2019/07/15 Python
安装python及pycharm的教程图解
2019/10/10 Python
关于初始种子自动选取的区域生长实例(python+opencv)
2020/01/16 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
英国男女奢华内衣和泳装购物网站:Figleaves
2017/01/28 全球购物
美国眼镜网:GlassesUSA
2017/09/07 全球购物
Structs界面控制层技术
2013/10/11 面试题
会计电算化个人求职信范文
2014/01/24 职场文书
软件售后服务方案
2014/05/29 职场文书
员工团队活动方案
2014/08/28 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书
HAM-2000摩机图
2021/04/22 无线电