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 相关文章推荐
jQuery1.6 类型判断实现代码
Sep 01 Javascript
浅谈js中的闭包
Mar 16 Javascript
jQuery简单操作cookie的插件实例
Jan 13 Javascript
深入学习AngularJS中数据的双向绑定机制
Mar 04 Javascript
详解javascript跨浏览器事件处理程序
Mar 27 Javascript
基于Bootstrap+jQuery.validate实现表单验证
May 30 Javascript
ES6中的rest参数与扩展运算符详解
Jul 18 Javascript
基于 Vue 实现一个酷炫的 menu插件
Nov 14 Javascript
node 使用 async 控制并发的方法
May 07 Javascript
命令行批量截图Node脚本示例代码
Jan 25 Javascript
基于jQuery实现挂号平台首页源码
Jan 06 jQuery
基于JavaScript实现年月日三级联动
Jun 22 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批量删除数据
2007/01/18 PHP
php email邮箱正则
2008/10/08 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
php中substr()函数参数说明及用法实例
2014/11/15 PHP
几个高效,简洁的字符处理函数
2007/04/12 Javascript
javascript Keycode对照表
2009/10/24 Javascript
javascript中的startWith和endWith的几种实现方法
2013/05/07 Javascript
js获取通过ajax返回的map型的JSONArray的方法
2014/01/09 Javascript
javascript图片相似度算法实现 js实现直方图和向量算法
2014/01/14 Javascript
邮箱下拉自动填充选择示例代码附图
2014/04/03 Javascript
原生Ajax 和jQuery Ajax的区别示例分析
2014/12/17 Javascript
防止Node.js中错误导致进程阻塞的办法
2016/08/11 Javascript
jq给页面添加覆盖层遮罩的实例
2017/02/16 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
vue2组件之select2调用的示例代码
2017/10/12 Javascript
简述vue状态管理模式之vuex
2018/08/29 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
p5.js实现动态图形临摹
2019/10/23 Javascript
[33:09]完美世界DOTA2联赛循环赛 Forest vs DM BO2第二场 10.29
2020/10/29 DOTA
Python中的ceil()方法使用教程
2015/05/14 Python
使用Python编写简单的画图板程序的示例教程
2015/12/08 Python
详解Django+Uwsgi+Nginx 实现生产环境部署
2018/11/06 Python
Python使用pydub库对mp3与wav格式进行互转的方法
2019/01/10 Python
浅谈Python3识别判断图片主要颜色并和颜色库进行对比的方法
2019/10/25 Python
pygame实现弹球游戏
2020/04/14 Python
python中sys模块是做什么用的
2020/08/16 Python
python 获取字典键值对的实现
2020/11/12 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
Canvas环形饼图与手势控制的实现代码
2019/11/08 HTML / CSS
为中国消费者甄选天下优品:网易严选
2016/08/11 全球购物
工厂厂长岗位职责
2013/11/08 职场文书
办理暂住证介绍信
2014/01/11 职场文书
公司接待方案
2014/03/08 职场文书
试用期旷工辞退通知书
2015/04/17 职场文书
如何在Mac上通过docker配置PHP开发环境
2021/05/29 PHP
Nginx配置之实现多台服务器负载均衡
2021/08/02 Servers