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脚本函数库 方便开发
Oct 13 Javascript
EasyUI 中 MenuButton 的使用方法
Jul 14 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
Nov 28 Javascript
JS实现网页表格自动变大缩小的方法
Mar 09 Javascript
AngularJS 与Bootstrap实现表格分页实例代码
Oct 14 Javascript
vue复合组件实现注册表单功能
Nov 06 Javascript
css和js实现弹出登录居中界面完整代码
Nov 26 Javascript
浅谈react受控组件与非受控组件(小结)
Feb 09 Javascript
Vue实现导出excel表格功能
Mar 30 Javascript
el-select数据过多懒加载的解决(loadmore)
May 29 Javascript
vue中的双向数据绑定原理与常见操作技巧详解
Mar 16 Javascript
vue接通后端api以及部署到服务器操作
Aug 13 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调用Twitter的RSS的实现代码
2010/03/10 PHP
深入浅析php中sprintf与printf函数的用法及区别
2016/01/08 PHP
Phpstorm+Xdebug断点调试PHP的方法
2018/05/14 PHP
PHP设计模式之单例模式定义与用法分析
2019/03/26 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
php桥接模式应用案例分析
2019/10/23 PHP
js完美解决IE6不支持position:fixed的bug
2015/04/24 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
bootstrap学习笔记之初识bootstrap
2016/06/21 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
使用JavaScript获取Request中参数的值方法
2016/09/27 Javascript
vue.js学习笔记之绑定style样式和class列表
2016/10/31 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
概述BootStrap中role=&quot;form&quot;及role作用角色
2016/12/08 Javascript
基于jQuery实现滚动刷新效果
2017/01/09 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
2017/02/11 Javascript
利用imgareaselect辅助后台实现图片上传裁剪
2017/03/02 Javascript
javascript 开发之网页兼容各种浏览器
2017/09/28 Javascript
layui layer select 选择被遮挡的解决方法
2019/09/21 Javascript
Vue使用vue-draggable 插件在不同列表之间拖拽功能
2020/03/12 Javascript
vue 限制input只能输入正数的操作
2020/08/05 Javascript
用Django写天气预报查询网站
2018/10/21 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
2018/12/05 Python
python3使用pandas获取股票数据的方法
2018/12/22 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
什么是python的函数体
2020/06/19 Python
详解python polyscope库的安装和例程
2020/11/13 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
2021/01/20 HTML / CSS
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
Notino希腊:购买香水和美容产品
2019/07/25 全球购物
迪士尼法国在线商店:shopDisney FR
2020/12/03 全球购物
渡河少年教学反思
2014/02/12 职场文书
大型会议接待方案
2014/03/01 职场文书
Redis 配置文件重要属性的具体使用
2021/05/20 Redis
Python使用永中文档转换服务
2022/05/06 Python