九宫格,里面有九张图片,用鼠标拖动其中1张图片置于另1张图片之上时并松开鼠标后,它俩的位置交换。**html 代码** ```html:run<!doctype html><html><head> <meta charset="utf-8"> <title>九宫格--位置交换</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } ul { width: 480px; height: 480px; padding: 5px; background: #CFC; position: relative; margin: 100px auto; } li { width: 150px; height: 150px; margin: 5px; cursor: move; -webkit-user-select: none; background: #FF9; overflow: hidden; float: left; } img { width: 100%; height: 100%; border: none; } </style></head> <body><ul> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li> <li><img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=46ac759c68ba5e51fc613502729240cf"></li></ul></body></html> <script> /*第一步:准备方法*/ function on(ele, type, fn) { if (ele.addEventListener) { ele.addEventListener(type, fn, false); } else { if (!ele["onEvent" + type]) { ele["onEvent" + type] = []; ele.attachEvent("on" + type, function () { run.call(ele) }); } var a = ele["onEvent" + type]; for (var i = 0; i < a.length; i++) { if (a[i] == fn)return; } a.push(fn); } } function run() { var e = window.event; var type = e.type; e.target = e.srcElement; e.pageX = (document.documentElement.scrollLeft || document.body.scrollLeft) + e.clientX; e.pageY = (document.documentElement.scrollTop || document.body.scrollTop) + e.clientY; e.preventDefault = function () { e.returnValue = false; }; e.stopPropagation = function () { e.cancelBubble = true; }; var a = this["onEvent" + type]; if (a && a.length) { for (var i = 0; i < a.length; i++) { if (typeof a[i] == "function") { a[i].call(this, e); } else { a.splice(i, 1); i--; } } } } function off(ele, type, fn) { if (ele.removeEventListener) { ele.removeEventListener(type, fn, false); } else { var a = ele["onEvent" + type]; if (a && a.length) { for (var i = 0; i < a.length; i++) { if (a[i] == fn) { a[i] = null; return; } } } } } function processThis(fn, context) { return function (e) { fn.call(context, e); }; } function EventEmitter() { } EventEmitter.prototype.on = function (type, fn) { if (!this["emitter" + type]) { this["emitter" + type] = []; } var a = this["emitter" + type]; for (var i = 0; i < a.length; i++) { if (a[i] == fn)return this; } a.push(fn); return this; }; EventEmitter.prototype.run = function (type, e) { var a = this["emitter" + type]; if (a && a.length) { for (var i = 0; i < a.length; i++) { if (typeof a[i] == "function") { a[i].call(this, e); } else { a.splice(i, 1); i--; } } } }; EventEmitter.prototype.off = function (type, fn) { var a = this["emitter" + type]; if (a && a.length) { for (var i = 0; i < a.length; i++) { if (a[i] == fn) { a[i] = null; break; } } } return this; }; function Drag(ele) { this.x = null; this.y = null; this.mx = null; this.my = null; this.ele = ele; this.obj = ele; this.DOWN = processThis(this.down, this); this.MOVE = processThis(this.move, this); this.UP = processThis(this.up, this); on(this.ele, "mousedown", this.DOWN);//对于这个on来说,我们只是使用者 //this.on;对于这个on来说,我们是开发者, } Drag.prototype.__proto__ = EventEmitter.prototype; //这是更安全的继承方法,一般在Node里都是采用这种方式实现继承。IE不支持 Drag.prototype = new EventEmitter;//相对这种方式来说,上边的写法更安全 Drag.prototype.down = function (e) { this.x = this.ele.offsetLeft; this.y = this.ele.offsetTop; this.mx = e.pageX; this.my = e.pageY; if (this.ele.setCapture) { this.ele.setCapture(); on(this.ele, "mousemove", this.MOVE); on(this.ele, "mouseup", this.UP); } else { on(document, "mousemove", this.MOVE); on(document, "mouseup", this.UP); } e.preventDefault(); this.run("abcde1", e); }; Drag.prototype.move = function (e) { this.ele.style.left = this.x + (e.pageX - this.mx) + "px"; this.ele.style.top = this.y + (e.pageY - this.my) + "px"; this.run("abcde2", e); }; Drag.prototype.up = function (e) { if (this.ele.releaseCapture) { this.ele.releaseCapture(); off(this.ele, "mousemove", this.MOVE); off(this.ele, "mouseup", this.UP); } else { off(document, "mousemove", this.MOVE); off(document, "mouseup", this.UP); } this.run("abcde3", e); }; var oRange = {l: 0, r: 600, t: 0, b: 300}; //相当于重新写了一个计算元素拖拽位置的方法,用这个方法,把原来的Drag.prototype.move覆盖掉 Drag.prototype.addRange = function (obj) { this.oRange = obj; this.on("abcde2", this.range); }; Drag.prototype.range = function range(e) { var oRange = this.oRange; var l = oRange.l, r = oRange.r, t = oRange.t, b = oRange.b; var currentL = this.x + (e.pageX - this.mx); var currentT = this.y + (e.pageY - this.my); if (currentL >= r) { this.ele.style.left = r + "px"; } else if (currentL <= l) { this.ele.style.left = l + "px"; } else { this.ele.style.left = currentL + "px"; } if (currentT >= b) { this.ele.style.top = b + "px"; } else if (currentT <= t) { this.ele.style.top = t + "px"; } else { this.ele.style.top = currentT + "px"; } }; Drag.prototype.border = function (width, color, style) { //允许不传参数,如果参数没有传,则这里给它指定默认的值 if (!width)width = "2"; if (!color)color = "#666"; if (!style)style = "dashed"; this.borderStyle = {width: width, color: color, style: style}; this.on("abcde1", this.addBorder); this.on("abcde3", this.removeBorder); }; Drag.prototype.addBorder = function () { var bs = this.borderStyle; this.ele.style.border = bs.width + "px " + bs.color + " " + bs.style; }; Drag.prototype.removeBorder = function () { this.ele.style.border = "none"; }; function Linear(t, b, c, d) { return c * t / d + b; } function animate(ele, obj, duration, effect, callback) { var oBegin = {};//用来保存多个方向begin; var oChange = {};//用来保存多个方向的change; var flag = 0;//用来记录各个方向的距离是否有效 for (var attr in obj) { var target = obj[attr] var begin = animate.getCss(ele, attr); var change = target - begin; if (change) {//判断一下此方向的运动距离有效,不为0 oBegin[attr] = begin; oChange[attr] = change; flag++; } } if (!flag)return;//如果各个方向的运动距离都是0,则结束动画的执行 var interval = 15; var times = 0; clearInterval(ele.timer); function step() { times += interval; if (times < duration) { for (var attr in oChange) { var change = oChange[attr]; var begin = oBegin[attr]; //var val=times/duration*change+begin; var val = Linear(times, begin, change, duration); animate.setCss(ele, attr, val); } } else { for (var attr in oChange) { var target = obj[attr]; animate.setCss(ele, attr, target); } clearInterval(ele.timer); ele.timer = null; if (typeof callback == "function") { callback.call(ele); } } } ele.timer = setInterval(step, interval); } animate.getCss = function (ele, attr) { if (window.getComputedStyle) { return parseFloat(window.getComputedStyle(ele, null)[attr]); } else { if (attr == "opacity") { var val = ele.currentStyle.filter; //"alpha(opacity=50)";//匹配到这样的一个字符串,然后把这个字符串中的数字部分拿到 var reg = /alpha\(opacity=(\d+(?:\.\d+)?)\)/; if (reg.test(val)) { return RegExp.$1 / 100; } else { //如果没有给IE中的不透明度赋值,则上边的正则为false return 1;//如果没有给不透明度赋值,则应该把默认值1返回 } //方法没有返回值,则此方法执行结束后留下一个undefined。即:没有返回值的方法返回的是undefined } else { return parseFloat(ele.currentStyle[attr]); } } }; animate.setCss = function (ele, attr, val) { if (attr == "opacity") { ele.style.opacity = val; ele.style.filter = "alpha(opacity=" + val * 100 + ")"; } else { ele.style[attr] = val + "px"; } }; /*第二步:碰撞检测*/ var oLis = document.getElementsByTagName("li"); //如下代码,循环倒着做就可以,这是为什么呢?一定要搞清楚 for (var i = oLis.length - 1; i >= 0; i--) { var oLi = oLis.item(i); oLi.style.left = (oLi.l = oLi.offsetLeft) + "px"; oLi.style.top = (oLi.t = oLi.offsetTop) + "px"; oLi.style.position = "absolute"; oLi.style.margin = 0; new Drag(oLi).on("abcde1", increaseIndex).on("abcde3", changePosition).on("abcde2", test); } var index = 0; function increaseIndex() { this.ele.style.zIndex = ++index; } function goHome() { animate(this.ele, {left: this.ele.l, top: this.ele.t}, 700); } //如果两个元素撞上了,则返回true;没有撞上,则返回false function isHited(b, r) { if (b.offsetLeft + b.offsetWidth < r.offsetLeft || b.offsetTop + b.offsetHeight < r.offsetTop || b.offsetLeft > r.offsetLeft + r.offsetWidth || b.offsetTop > r.offsetTop + r.offsetHeight) { return false; } else { return true; } } function test() { this.aHited = []; for (var i = 0; i < oLis.length; i++) { var oLi = oLis.item(i); if (oLi == this.ele)continue; if (isHited(this.ele, oLi)) { this.aHited.push(oLi); oLi.style.backgroundColor = "red"; } else { oLi.style.backgroundColor = ""; } } } function changePosition() { var a = this.aHited; if (a && a.length) { for (var i = 0; i < a.length; i++) { var oLi = a[i]; //计算被拖拽的元素和撞上的元素之间的距离,并且把距离保存到distance属性上 oLi.distance = Math.sqrt(Math.pow(this.ele.offsetLeft - oLi.offsetLeft, 2) + Math.pow(this.ele.offsetTop - oLi.offsetTop, 2)); oLi.style.backgroundColor = ""; } //排序,找出和被拖拽元素最短的那个元素 a.sort(function (a, b) { return a.distance - b.distance }); var shortest = a[0]; shortest.style.backgroundColor = "orange"; this.ele.style.backgroundColor = "orange"; //交换位置 animate(shortest, {left: this.ele.l, top: this.ele.t}, 700); animate(this.ele, {left: shortest.l, top: shortest.t}, 700); var l = this.ele.l, t = this.ele.t; this.ele.l = shortest.l; this.ele.t = shortest.t; shortest.l = l; shortest.t = t; } else {//如果没有撞上的元素,则返回原始位置 animate(this.ele, {left: this.ele.l, top: this.ele.t}, 700); } }</script>```
原文地址:https://www.cnblogs.com/gushixianqiancheng/p/10967164.html
时间: 2024-10-02 15:46:36