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 相关文章推荐
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
Aug 04 Javascript
jquery.cookie.js用法实例详解
Dec 25 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
May 26 Javascript
Vue学习笔记进阶篇之vue-cli安装及介绍
Jul 18 Javascript
vue使用vue-cli快速创建工程
Jul 28 Javascript
webpack使用 babel-loader 转换 ES6代码示例
Aug 21 Javascript
node.js将MongoDB数据同步到MySQL的步骤
Dec 10 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
Dec 11 Javascript
Bootstrap4 gulp 配置详解
Jan 06 Javascript
详解js获取video任意时间的画面截图
Apr 17 Javascript
vue日历/日程提醒/html5本地缓存功能
Sep 02 Javascript
Vue中插槽slot的使用方法与应用场景详析
Jun 08 Vue.js
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定时执行计划任务的多种方法小结
2011/12/19 PHP
不使用php api函数实现数组的交换排序示例
2014/04/13 PHP
php微信公众平台开发之获取用户基本信息
2015/08/17 PHP
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
读jQuery之八 包装事件对象
2011/06/21 Javascript
IE8提示Invalid procedure call or argument 异常的解决方法
2012/09/30 Javascript
JS 各种网页尺寸判断实例方法
2013/04/18 Javascript
jQuery性能优化的38个建议
2014/03/04 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
2016/06/28 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
vue中实现图片和文件上传的示例代码
2018/03/16 Javascript
使用Vue组件实现一个简单弹窗效果
2018/04/23 Javascript
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
vue eslint简要配置教程详解
2019/07/26 Javascript
如何正确理解vue中的key详解
2019/11/02 Javascript
jQuery操作事件完整实例分析
2020/01/10 jQuery
深入webpack打包原理及loader和plugin的实现
2020/05/06 Javascript
Python运行的17个时新手常见错误小结
2012/08/07 Python
python搜索指定目录的方法
2015/04/29 Python
Python实现简单字典树的方法
2016/04/29 Python
python 基础教程之Map使用方法
2017/01/17 Python
Python并发编程协程(Coroutine)之Gevent详解
2017/12/27 Python
python使用mysql的两种使用方式
2018/03/07 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python按钮的响应事件详解
2019/03/04 Python
简单了解django索引的相关知识
2019/07/17 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
2020/03/28 Python
python collections模块的使用
2020/10/16 Python
纯CSS3制作的鼠标悬停时边框旋转
2017/01/03 HTML / CSS
eBay英国购物网站:eBay.co.uk
2019/06/19 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
生产副总岗位职责
2013/11/28 职场文书
分公司任命书
2014/06/06 职场文书
企业群众路线教育实践活动心得体会
2014/11/03 职场文书
证劵公司反洗钱宣传活动总结
2015/05/08 职场文书
Mysql服务添加 iptables防火墙策略的方案
2021/04/29 MySQL