您好,欢迎访问一九零五行业门户网

封装一个自己的模块实例详解

试着封装了一个拖拽模块。过程中经历了一些曲折,最开始我是打算只用style.left的方式,但是这个需要设置position:absolute。可能对代码造成一定影响。虽然css的transform会影响兼容,但这里我还是使用了这个属性的translate来完成移动。
只用style完成的代码话不多说,直接上代码:
html和css,这里必须设置position,第一次写这段代码的时候忘了,结果尽管js写对了,效果完全出不来....真是短路了
<!doctype html> <html lang="en"> <head>     <meta charset="utf-8">     <title>学习</title>     <style>         *{             margin: 0;             padding: 0;         }         #box{             width: 200px;             height: 200px;             background: #6f6;             font-size: 20px;             cursor:move;             position: absolute;         }     </style> </head> <body>   <p id="box"></p>   <script src="js/drag_module.js"></script> </body> </html>
重点!!js;    //这个分号是为了防止其他的模块最后忘记加分号,导致错误。 (function() {      //构造函数,属于每一个实例   function drag(selector) {     this.elem = typeof selector == 'object' ? selector : document.getelementbyid(selector);     //鼠标初始位置     this.startx = 0;     this.starty = 0;     //元素初始位置     this.sourcex = 0;     this.sourcey = 0;     this.init();   }   //原型,共有的   drag.prototype = {     constructor: drag,     init: function() {       this.setdrag();     },     //用于获取元素当前的位置信息     getposition: function() {       var that = this;       var pos = {};       pos = {         x: that.elem.offsetleft,         y: that.elem.offsettop       };       return pos;     },     //用来设置当前元素的位置     setposition: function(pos) {       this.elem.style.left = pos.x + 'px';       this.elem.style.top = pos.y + 'px';     },     //该方法用来绑定事件     setdrag: function() {       var self = this;       this.elem.addeventlistener('mousedown', start, false);       function start(event) {         self.startx = event.pagex;         self.starty = event.pagey;         var pos = self.getposition();         self.sourcex = pos.x;         self.sourcey = pos.y;         document.addeventlistener('mousemove', move, false);         document.addeventlistener('mouseup', end, false);       }       function move(event) {         //总体思想:鼠标距浏览器距-鼠标距元素距离         var currentx = event.pagex; //当前的鼠标x位置         var currenty = event.pagey; //当前的鼠标y位置         var distancex = currentx - self.startx; //鼠标移动的距离x         var distancey = currenty - self.starty; //鼠标移动的距离y         self.setposition({           x: self.sourcex + distancex,           y: self.sourcey + distancey         });       }       function end(event) {         document.removeeventlistener('mousemove', move);         document.removeeventlistener('mouseup', end);       }     }   };      //暴露在外   window.drag = drag; })(); new drag('box');
这段代码是比较好理解的,在一开始看波大神的代码时,对于translate的运用实际上我没看太明白,因为没想到为啥要用到正则......
虽然比较简单,但是我们还是要分析一下这段代码的原理:
1.自执行函数里有一个构造函数drag(),在构造函数里我们设置的方法和属性时每一个构造函数实例独有的,比如他们的位置信息等。而在原型里的有三个方法:分别是获取元素位置信息的getposition()、设置元素位置的setposition()和绑定事件的setdrag(),这三个因为是公用的,为了节省资源,我们就放在原型里了。
2.这段代码执行的原理是:当鼠标按下时,获取元素初始位置信息sourcex/y、鼠标初始位置信息startx/y;当鼠标移动完成时,获取鼠标新的位置currentx/y,两个鼠标位置相减就能得到鼠标移动的距离distancex/y,这同时也是元素移动的距离,然后,我们把这个值赋给元素的style.left/top。元素的拖拽就实现了。
transform和style的结合由于技术的发展,越来越多的设备开始支持css3了,加上style的资源占用的更多,效率方面存在问题,所以我们考虑使用transform。浏览器的兼容写法我们首先在函数drag()前加上私有属性:
var transform = gettransform();
在下面再加上私有方法:
function gettransform() {     var transform = ,       pstyle = document.createelement('p').style,       transformarr = ['transform', 'webkittransform', 'moztransform', 'mstransform', 'otransform'],       i = 0,       l = transformarr.length;     for (; i < l; i++) {       if (transformarr[i] in pstyle) {         return transform = transformarr[i];       }     }     return transform;   }
ps:记住createelement()这个方法,下次判断浏览器兼容时用得着!我们还需要在getposition()的下面加上一个函数,用同样的形式:
gettranslate: function() {       var val = {};       var transformvalue = document.defaultview.getcomputedstyle(this.elem, false)[transform];       if(transformvalue=='none'){         val={x:0,y:0};       }else{         var transformarr = transformvalue.match(/-?\d+/g);         val = {           x: number(transformarr[4]),           y: number(transformarr[5])         };       }       return val;     },
ps:之所以要判断transformvalue是否为none,是因为在初始化状态是,元素未被设置transform属性,这样正则之后的数组是找不到[4][5] 的,所以我们让val的两个属性为0,也就是稍后会成为的transform的translatex和translatey的值。继续写代码。上面一段我们用来提取translate的x、y值。看下面一段:
getposition: function() {       var that = this;       var pos = {};       if(transform){         var val=this.gettranslate();         pos={           x:val.x,           y:val.y         };       }else{         pos = {           x: that.elem.offsetleft,           y: that.elem.offsettop         };       }       return pos;     },
注意上面一段代码我们修改的的内容,在这里我们增加了一个判断:即当支持transform属性的浏览器存在时,我们会用transform属性修改元素的值,把之前在gettranslate中得到的x、y赋值给pos的x、y。在上面一段代码中,我们会根据浏览器的情况,用不同的方法取到相同的值,val的值来自gettranslate(),是我们从元素的transform中提取出来的。同样,在下面的setposition()中,我们也要设置if判断。
setposition: function(pos) {       if (transform) {         this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)';       } else {         this.elem.style.left = pos.x + 'px';         this.elem.style.top = pos.y + 'px';       }     },
这一段没什么好讲的,就是用不同的形式赋值而已。
到这里,这个模块就封装完毕了。接下来让我们看看完整代码:
; (function() {   //私有属性   var transform = gettransform();   //构造函数,属于每一个实例   function drag(selector) {     this.elem = typeof selector == 'object' ? selector : document.getelementbyid(selector);     //鼠标初始位置     this.startx = 0;     this.starty = 0;     //元素初始位置     this.sourcex = 0;     this.sourcey = 0;     this.init();   }   //原型,共有的   drag.prototype = {     constructor: drag,     init: function() {       this.setdrag();     },     //用于获取元素当前的位置信息     getposition: function() {       var that = this;       var pos = {};       if(transform){         var val=this.gettranslate();         pos={           x:val.x,           y:val.y         };       }else{         pos = {           x: that.elem.offsetleft,           y: that.elem.offsettop         };       }       return pos;     },     //获取translate值     gettranslate: function() {       var val = {};       var transformvalue = document.defaultview.getcomputedstyle(this.elem, false)[transform];       if(transformvalue=='none'){         val={x:0,y:0};       }else{         var transformarr = transformvalue.match(/-?\d+/g);         val = {           x: number(transformarr[4]),           y: number(transformarr[5])         };       }       return val;     },     //用来设置当前元素的位置     setposition: function(pos) {       if (transform) {         this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)';       } else {         this.elem.style.left = pos.x + 'px';         this.elem.style.top = pos.y + 'px';       }     },     //该方法用来绑定事件     setdrag: function() {       var self = this;       this.elem.addeventlistener('mousedown', start, false);       function start(event) {         self.startx = event.pagex;         self.starty = event.pagey;         var pos = self.getposition();         self.sourcex = pos.x;         self.sourcey = pos.y;         document.addeventlistener('mousemove', move, false);         document.addeventlistener('mouseup', end, false);       }       function move(event) {         //总体思想:鼠标距浏览器距-鼠标距元素距离         var currentx = event.pagex; //当前的鼠标x位置         var currenty = event.pagey; //当前的鼠标y位置         var distancex = currentx - self.startx; //鼠标移动的距离x         var distancey = currenty - self.starty; //鼠标移动的距离y         self.setposition({           x: self.sourcex + distancex,           y: self.sourcey + distancey         });       }       function end(event) {         document.removeeventlistener('mousemove', move);         document.removeeventlistener('mouseup', end);       }     }   };   //私有方法,用来获取transform的兼容写法   function gettransform() {     var transform = ,       pstyle = document.createelement('p').style,       transformarr = ['transform', 'webkittransform', 'moztransform', 'mstransform', 'otransform'],       i = 0,       l = transformarr.length;     for (; i < l; i++) {       if (transformarr[i] in pstyle) {         return transform = transformarr[i];       }     }     return transform;   }   //暴露在外   window.drag = drag; })(); new drag('box');
相关推荐:
javascript全局变量封装模块实现代码_javascript技巧
以上就是封装一个自己的模块实例详解的详细内容。
其它类似信息

推荐信息