拖拽的HTML代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>拖拽</title> <style type="text/css"> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; background: #e1e1e1; overflow: hidden; } #box { visibility: hidden; /*隐藏占位置*/ position: absolute; top: 0; left: 0; width: 200px; height: 200px; background: lightblue; cursor: move; } </style> </head> <body> <div id="box"></div> <!--<script charset="utf-8" type="text/javascript" src="js/utils.min.js"></script>--> <script charset="utf-8" type="text/javascript" src="js/event.js"></script> <script type="text/javascript"> var oBox = document.getElementById("box"); //JS让盒子处于屏幕正中间位置 var winW = document.documentElement.clientWidth || document.body.clientWidth, winH = document.documentElement.clientHeight || document.body.clientHeight;//一屏幕的宽高 var boxW = oBox.offsetWidth, boxH = oBox.offsetHeight;//盒子宽和高 oBox.style.left = (winW - boxW) / 2 + "px"; oBox.style.top = (winH - boxH) / 2 + "px"; oBox.style.visibility = "visible"; //JS实现拖拽:mouseover mouseout mouseup zhufengEvent.on(oBox, "mousedown", down); function down(e) { this["strX"] = e.clientX;//鼠标起始位置 this["strY"] = e.clientY; this["strL"] = this.style.left;//盒子起始位置(获取行内样式) this["strT"] = this.style.top; //-> if (this.setCapture) { this.setCapture();//-> this.setCapture();//->在IE和火狐浏览器中支持这个方法:把鼠标和当前的盒子this绑定在一起了,不管鼠标多快,盒子都可以跟着运动 zhufengEvent.on(oBox, "mousemove", move); zhufengEvent.on(oBox, "mouseup", up); return; } //谷歌:不管鼠标运动多快,始终逃不出document,这样的话我们就把mousemouve/mouseup绑定给document,当方法执行的时候控制盒子运动 //zhufengEvent.processThis(move,this);//->this就是oBox //zhufengEvent.processThis(move,oBox); this["MOVE"] = zhufengEvent.processThis(move, this); this["UP"] = zhufengEvent.processThis(up, this); zhufengEvent.on(document, "mousemove", this["MOVE"]); zhufengEvent.on(document, "mouseup", this["UP"]); } function move(e) { var changeX = e.clientX - parseFloat(this["strX"]);//私有变量 鼠标坐标值是一个值 可以加parseFloat var changeY = e.clientY - parseFloat(this["strY"]); var curL = parseFloat(this["strL"]) + changeX;//120px字符串 var curT = parseFloat(this["strT"]) + changeY; var minL = 0, minT = 0, maxL = winW - boxW, maxT = winH - boxH; curL = curL <= minL ? minL : (curL >= maxL ? maxL : curL); curT = curT <= minT ? minT : (curT >= maxT ? maxT : curT); oBox.style.left = curL + "px"; oBox.style.top = curT + "px"; } //-> function up(e) { if (this.releaseCapture) { this.releaseCapture();//->解绑 zhufengEvent.off(oBox, "mousemove", move); zhufengEvent.off(oBox, "mouseup", up); return; } zhufengEvent.off(document, "mousemove", this["MOVE"]); zhufengEvent.off(document, "mouseup", this["UP"]); } </script> </body> </html>
引用的event.js代码:
var zhufengEvent = (function () { function processThis(callBack, context) { var outerArg = Array.prototype.slice.call(arguments, 2);//[100,200] return function () { var innerArg = Array.prototype.slice.call(arguments, 0); //[e]数组 callBack.apply(context, outerArg.concat(innerArg));//[100,200,e] } } function bind(curEle, type, fn) { //->标准浏览器 if ("addEventListener" in curEle) {//document.addEventListener curEle.addEventListener(type, fn, false);//false:冒泡阶段 return; } //->IE6~8 var tempFn = processThis(fn, curEle); tempFn.photo = fn; if (!curEle["myBind" + type]) { curEle["myBind" + type] = []; } //-> var ary = curEle["myBind" + type]; for (var i = 0; i < ary.length; i++) { if (ary[i].photo === fn) { return; } } ary.push(tempFn); curEle.attachEvent("on" + type, tempFn); } //->unbind:给当前元素的某一个行为移除某一个绑定方法 function unbind(curEle, type, fn) { if ("removeEventListener" in curEle) {//document.addEventListener curEle.removeEventListener(type, fn, false);//false:冒泡阶段 return; } //->IE6~8 var ary = curEle["myBind" + type]; if (ary) { for (var i = 0; i < ary.length; i++) { var tempFn = ary[i]; if (tempFn.photo === fn) { curEle.detachEvent("on" + type, tempFn);//->内置的事件池中移除 ary.splice(i, 1);//->在自定义属性中也把化妆后的tempFn移除掉 break; } } } } function on(curEle, type, fn) { if (!curEle["myEvent" + type]) { curEle["myEvent" + type] = []; } var ary = curEle["myEvent" + type]; //->如果当前事件池已经存储了这个方法,我们就不需要再存储了 for (var i = 0; i < ary.length; i++) { if (ary[i] === fn) { return; } } ary.push(fn); bind(curEle, type, fire); } //->off:在自己创建的事件池中移除对应的方法 function off(curEle, type, fn) { var ary = curEle["myEvent" + type]; if (ary) { for (var i = 0; i < ary.length; i++) { if (ary[i] === fn) { //ary.splice(i, 1);//->这样每一次移除会把自定义事件池中方法对应的索引进行修改,在执行fire的时候,索引就乱了->"数组塌陷问题" ary[i] = null; return; } } } } function fire(e) { //->统一把e处理兼容了,以后在方法中的e就不需要再处理兼容了 if (window.event) { //IE6~8 //e = window.event; e.target = e.srcElement; e.pageX = e.clientX + (document.documentElement.scrollLeft) || document.body.scrollLeft; e.pageY = e.clientY + (document.documentElement.scrollTop) || document.body.scrollTop; e.preventDefault = function () { e.returnValue = false; }; e.stopPropagation = function () { e.cancelBubble = true; }; } //this->curELe var ary = this["myEvent" + e.type]; // console.log(e.type); if (ary) { for (var i = 0; i < ary.length; i++) { var curFn = ary[i]; //curFn();//->this->window 应该让每一个方法中的this都变成当前元素this,并且还需要把事件对象传递给对应的方法 if (typeof curFn === "function") { curFn.call(this, e); } else { //->应该是我们在off移除后把这一项的值赋值为null,那此时我们把为null的这一项移除掉 ary.splice(i, 1); i--; } } } } return { on: on, off: off, processThis: processThis } })();