这篇文章主要介绍了 javascript 实现拖动元素交换位置的方法,类似拼图游戏拖拽卡片效果,感兴趣的小伙伴们可以参考一下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
运行效果截图如下:
具体代码如下:
代码:
- 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";
- }
- }
来源: http://www.phperz.com/article/17/0410/268433.html