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>

  • 相关阅读:
    Head first javascript(七)
    Python Fundamental for Django
    Head first javascript(六)
    Head first javascript(五)
    Head first javascript(四)
    Head first javascript(三)
    Head first javascript(二)
    Head first javascript(一)
    Sicily 1090. Highways 解题报告
    Python GUI programming(tkinter)
  • 原文地址:https://www.cnblogs.com/quinnxu/p/3260315.html
Copyright © 2011-2022 走看看