zoukankan      html  css  js  c++  java
  • 一个轻量级javascript框架的设计模式

    公司一直使用jQuery框架,一些小的项目还是觉得jQuery框架太过于强大了,于是自己周末有空琢磨着写个自己的框架。谈到js的设计模式,不得不说说js的类继承机制,javascript不同于PHP可以轻松的实现类继承,不过javascript的类继承方法还是有的,常见的有构建函数、原型扩展、综合……,也有一些专门写类的函数,例如jQuery的作者有个类继承函数。关于类继承写法可以简单看看这篇文章

    我自己写的框架也不知道叫什么名字,刚开始写的时候随手写了个W(姓拼音,之前写过jQuery弹出框插件wBox),现在写这篇文章重新整理了一下思想,换了YQ(名字拼音,你懂的~)。

    核心代码

    框架设计的时候尽量做到了支持链式写法,也就是返回this,可以$(selector).handler1().handler2()……无限写下去,只要不是有返回值的就可以继续。包括了eventdomcss,还有fadeInfadeOut动画(因为再重构爱墙[html5+css3]版,所有顺手加上了这个功能)。如果配合sizzle选择器就更牛了!

    下面说说框架的核心代码,等完善了之后跟新版html5爱墙一起放出,主要的代码如下:

     

      1 (function(window,document){
      2         var DOC = document,YQ = window.$ =function(selector){
      3                 if(!selector){
      4                         return YQ.elems
      5                 }
      6                 typeof selector ==='string'&&(selector = getElements(selector));//简单的判断是dom对象,还是字符串,字符串则开始选择器
      7                 return superElems(selector);
      8         }
      9         function superElems(elems){
     10                 if(elems){
     11                         if(elems.nodeType){//判断是否为DOM
     12                                 if(typeof elems.getAttribute!=="unknown"){
     13                                         var temp = elems;
     14                                         elems =[];
     15                                         elems[0]= temp;//把本身作为超级对象的第一个,其他方法进行扩展
     16                                         for(var i in YQ.elems){
     17                                                 //扩展对象,保留已有的方法
     18                                                 typeof elems[i]==="undefined"&&(elems[i]= YQ.elems[i])
     19                                         }
     20                                 }
     21                         }else{//如果为对象,则对对象进行扩展
     22                                 elems = YQ.extend(elems,YQ.elems);
     23                         }
     24                 }
     25                 return elems;
     26         }
     27         function getElements(selector){
     28                 //伟大的选择器,可以使用sizzle
     29                 var dom = DOC.getElementById(selector);//……
     30                 return dom;
     31         }
     32         YQ.tool={
     33                 isFunction:function(obj){//简单的判断是否为函数
     34                         return obj &&typeof obj ==="function";
     35                 }
     36         }
     37         //此处为超级对象一些扩展
     38         YQ.elems={
     39                 each:function(dom,callback){//强大的each
     40                         if(YQ.tool.isFunction(dom)){
     41                                 arguments.callee.call(this,this,dom);
     42                         }else{
     43                                 for(var i =0, len = dom.length; i < len; i++){
     44                                         callback.call(dom, i, dom[i]);
     45                                 }
     46                         }
     47                         returnthis;
     48                 },
     49                 find:function(selector){
     50                         var doms =[];
     51                         this.each(function(i,dom){
     52                                 doms.push(YQ.DOM.find(selector,dom));
     53                         })
     54                         return superElems(doms);
     55                 }
     56         }
     57         YQ.each= window.Array.prototype.each= YQ.elems.each;//扩展Array
     58         YQ.extend=function(subClass,baseClass){
     59                 for(var i in baseClass){
     60                         subClass[i]= baseClass[i];
     61                 }
     62                 return subClass;
     63         }
     64         YQ.AJAX={}
     65         YQ.CSS={
     66                 names:{
     67                         'float':'cssFloat',//区分cssFloat or styleFloat
     68                         opacity:'opacity'
     69                         //……
     70                 }
     71         }
     72         YQ.browser={
     73                 isIE:'',
     74                 isFirefox:'',
     75                 version:'3.6'
     76                 //……
     77         }
     78         YQ.event={
     79                 names:{
     80                         mousewheel:YQ.browser?"DOMMouseScroll":"mousewheel"
     81                 },
     82                 fix:function(e){
     83                         if(e && e.clone)return e;//如果已经处理了,直接返回
     84                         e = window.event|| e;//event是全局变量
     85                         var fixE ={
     86                                 clone:true,
     87                                 stop:function(){//冒泡
     88                                         if(e&&e.stopPropagation){
     89                                                 e.stopPropagation();
     90                                         }else{
     91                                                 e.cancleBubble=true
     92                                         }
     93                                 },
     94                                 prevent:function(){//默认动作
     95                                         if(e && e.preventDefault){
     96                                                 e.preventDefault();
     97                                         }else{
     98                                                 e.returnValue=false;
     99                                         }
    100                                 },
    101                                 target:e.target|| e.srcElement,
    102                                 x:e.clientX|| e.pageX,
    103                                 Y:e.clientY|| e.pageY,
    104                                 //鼠标滚轮事件统一处理
    105                                 wheel:e.wheelDelta/120||-e.detail/3
    106                         }
    107                         return fixE;
    108                 }
    109         }
    110         YQ.DOM={
    111                 find:function(selector,parentDom){
    112                         //do something
    113                 }
    114         }
    115 })(window,document);

     

    简单的分析

    代码中的注释还算详细,结合注释就可以看懂,下面我再啰嗦几句,高手飘过,欢迎拍砖……

    总得来看是个匿名函数,定义了全局变量$(似乎都喜欢美元,如果有喜欢的人民币的,下次加上),函数里面有个YQ的对象,有很多function,包括一些私有的。

    使用$可以作为选择器,如果为空,则返回YQ.elems对象,选择后的DOM根据YQ.elems进行扩展,最后得到的就是注释里面说的superElems(此处创建superElems方法参考了下jRaiser),跟jQuerysuperElems类似,绑定了很多方法,可以方便的进行操作,YQ的方法可以通过YQ.elems扩展到选择器选择的对象上去,而选择器主要的函数getElements,可以使用sizzle,这样就方便了dom操作,不过sizzle似乎也是代码太多,此处将来会支持简单的标签,#ID,.class,标签+class选择器。

    另外框架中中对一些Arraystring进行了扩展,例如上面的Array.each方法,YQ.elems.each是重量级的函数方法,可以支持superElems的遍历(返回本身),还可以支持简单数组的遍历。

    框架中还对一些兼容性进行了处理,例如YQ.event.fix处理事件,css中处理float

    基本就这些了,今天就先说核心的部分,其实通过这段代码已经很清晰的了解到这个框架的思想了,后续继续给力的coding,补充扩展……

    目前为止,框架不到800行代码,包括了常见的jQuery方法,压缩后不到9kgzip 4.5K~

    写在最后

    本想写一系列的文章,可是敲了几个字又不知道说啥,今后学习下司徒正美追求短小精悍的博文~呵呵

     

    源文档 <http://js8.in/677.html>

  • 相关阅读:
    Jekyll教程——精心收藏
    Git初步学习
    跨域
    ReentraneLock & synchronized & AQS
    JAVA UnSafe & CAS & AtomicInteger
    JAVA事务
    mysql 相关语句及优化
    多线程下 SimpleDateFormat
    JAVA 之 七种单例模式
    happens-before
  • 原文地址:https://www.cnblogs.com/quinnxu/p/3260315.html
Copyright © 2011-2022 走看看