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 相关文章推荐
Add a Table to a Word Document
Jun 15 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
May 14 Javascript
js获取滚动距离的方法
May 30 Javascript
js图片轮播效果实现代码
Apr 18 Javascript
最原始的jQuery注册验证方式
Oct 11 Javascript
Vue2学习笔记之请求数据交互vue-resource
Feb 23 Javascript
JS实现双击内容变为可编辑状态
Mar 03 Javascript
如何理解Vue的.sync修饰符的使用
Aug 17 Javascript
ES7中利用Await减少回调嵌套的方法详解
Nov 01 Javascript
ES6中javascript实现函数绑定及类的事件绑定功能详解
Nov 08 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
Jan 23 Javascript
详解react-refetch的使用小例子
Feb 15 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
在WIN98下以apache模块方式安装php
2006/10/09 PHP
joomla jce editor 解决上传中文名文件失败问题
2013/06/09 PHP
PHP curl 抓取AJAX异步内容示例
2014/09/09 PHP
php按单词截取字符串的方法
2015/04/07 PHP
微信支付开发维权通知实例
2016/07/12 PHP
php实现图片以base64显示的方法
2016/10/13 PHP
PHP+Session防止表单重复提交的解决方法
2018/04/09 PHP
一些常用的Javascript函数
2006/12/22 Javascript
Prototype使用指南之array.js
2007/01/10 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
js操作iframe的一些方法介绍
2013/06/25 Javascript
客户端js判断文件类型和文件大小即限制上传大小
2013/11/20 Javascript
JQuery跳出each循环的方法
2015/04/16 Javascript
如何解决easyui自定义标签 datagrid edit combobox 手动输入保存不上
2015/12/26 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
Js调用Java方法并互相传参的简单实例
2016/08/11 Javascript
Bootstrap缩略图的创建方法
2017/03/22 Javascript
JS实现简单表格排序操作示例
2017/10/07 Javascript
vue.js实现插入数值与表达式的方法分析
2018/07/06 Javascript
vue删除html内容的标签样式实例
2018/09/13 Javascript
微信小程序实现判断是分享到群还是个人功能示例
2019/05/03 Javascript
浅谈vue.use()方法从源码到使用
2019/05/12 Javascript
Python 私有函数的实例详解
2017/09/11 Python
Python 文件操作的详解及实例
2017/09/18 Python
Python数据结构与算法之列表(链表,linked list)简单实现
2017/10/30 Python
python实现杨氏矩阵查找
2019/03/02 Python
基于Python生成个性二维码过程详解
2020/03/05 Python
python将音频进行变速的操作方法
2020/04/08 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
2020/06/18 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
应届生求职简历的自我评价怎么写
2013/10/23 职场文书
客服主管岗位职责
2013/12/13 职场文书
国际贸易专业求职信
2014/06/04 职场文书
护士个人年度总结范文
2015/02/13 职场文书
Python anaconda安装库命令详解
2021/10/16 Python
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL