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判断录入的日期是否合法
Jan 08 Javascript
二级域名或跨域共享Cookies的实现方法
Aug 07 Javascript
Javascript字符串对象的常用方法简明版
Jun 26 Javascript
js事件冒泡、事件捕获和阻止默认事件详解
Aug 04 Javascript
JS实现滑动门效果的方法详解
Dec 19 Javascript
jQuery解析返回的xml和json方法详解
Jan 05 Javascript
Angular2实现自定义双向绑定属性
Mar 22 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
May 16 Javascript
Vue2.0生命周期的理解
Aug 20 Javascript
React 项目迁移 Webpack Babel7的实现
Sep 12 Javascript
JSONP解决JS跨域问题的实现
May 25 Javascript
Vue $attrs &amp; inheritAttr实现button禁用效果案例
Dec 07 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
杏林同学录(九)
2006/10/09 PHP
PHP中文分词的简单实现代码分享
2011/07/17 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
PHP中的socket_read和socket_recv区别详解
2015/02/09 PHP
Symfony实现行为和模板中取得request参数的方法
2016/03/17 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
2019/12/13 PHP
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
javascript Array.remove() 数组删除
2009/08/06 Javascript
页面中js执行顺序
2009/11/09 Javascript
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
2012/01/08 Javascript
javascript一元操作符(递增、递减)使用示例
2013/08/07 Javascript
JQuery EasyUI 数字格式化处理示例
2014/05/05 Javascript
JavaScript数组Array对象增加和删除元素方法总结
2015/01/20 Javascript
JavaScript计时器示例分析
2015/02/05 Javascript
js+css实现上下翻页相册代码分享
2015/08/18 Javascript
js密码强度校验
2015/11/10 Javascript
JavaScript中的boolean布尔值使用学习及相关技巧讲解
2016/05/26 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
详解jQuery插件开发方式
2016/11/22 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
今天,小程序正式支持 SVG
2019/04/20 Javascript
Java 生成随机字符的示例代码
2021/01/13 Javascript
python pandas dataframe 行列选择,切片操作方法
2018/04/10 Python
使用Python制作自动推送微信消息提醒的备忘录功能
2018/09/06 Python
python2与python3中关于对NaN类型数据的判断和转换方法
2018/10/30 Python
python 随机森林算法及其优化详解
2019/07/11 Python
什么是python的id函数
2020/06/11 Python
Python包资源下载路径报404解决方案
2020/11/05 Python
美国市场上最实惠的送餐服务:Dinnerly
2018/03/18 全球购物
意大利在线药房:shop-farmacia.it
2019/03/12 全球购物
音乐之声音乐广播稿
2014/09/10 职场文书
临时用工协议书范本
2014/10/29 职场文书
2016幼儿园教师节新闻稿
2015/11/25 职场文书
《秦兵马俑》教学反思
2016/02/24 职场文书