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

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

核心代码

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

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

(function(window,document){ 
    var DOC = document,YQ = window.$ = function(selector){ 
        if(!selector){ 
            return YQ.elems 
        } 
        typeof selector === 'string' && (selector = getElements(selector));//简单的判断是dom对象,还是字符串,字符串则开始选择器 
        return superElems(selector); 
    } 
    function superElems(elems){ 
        if(elems){ 
            if(elems.nodeType){//判断是否为DOM 
                if(typeof elems.getAttribute !=="unknown"){ 
                    var temp = elems; 
                    elems = []; 
                    elems[0] = temp;//把本身作为超级对象的第一个,其他方法进行扩展 
                    for(var i in YQ.elems){ 
                        //扩展对象,保留已有的方法 
                        typeof elems[i] === "undefined" && (elems[i] = YQ.elems[i]) 
                    } 
                } 
            }else{//如果为对象,则对对象进行扩展 
                elems = YQ.extend(elems,YQ.elems); 
            } 
        } 
        return elems; 
    } 
    function getElements(selector){ 
        //伟大的选择器,可以使用sizzle 
        var dom = DOC.getElementById(selector);//…… 
        return dom; 
    } 
    YQ.tool = { 
        isFunction:function(obj){//简单的判断是否为函数 
            return obj && typeof obj ==="function"; 
        } 
    } 
    //此处为超级对象一些扩展 
    YQ.elems = { 
        each:function(dom,callback){//强大的each 
            if(YQ.tool.isFunction(dom)){ 
                arguments.callee.call(this,this,dom); 
            }else{ 
                for (var i = 0, len = dom.length; i < len; i++) { 
                    callback.call(dom, i, dom[i]); 
                } 
            } 
            return this; 
        }, 
        find:function(selector){ 
            var doms = []; 
            this.each(function(i,dom){ 
                doms.push(YQ.DOM.find(selector,dom)); 
            }) 
            return superElems(doms); 
        } 
    } 
    YQ.each = window.Array.prototype.each = YQ.elems.each;//扩展Array 
    YQ.extend = function(subClass,baseClass){ 
        for(var i in baseClass){ 
            subClass[i] = baseClass[i]; 
        } 
        return subClass; 
    } 
    YQ.AJAX = {} 
    YQ.CSS = { 
        names:{ 
            'float':'cssFloat',//区分cssFloat or styleFloat 
            opacity:'opacity' 
            //…… 
        } 
    } 
    YQ.browser = { 
        isIE:'', 
        isFirefox:'', 
        version:'3.6' 
        //…… 
    } 
    YQ.event = { 
        names:{ 
            mousewheel:YQ.browser?"DOMMouseScroll":"mousewheel" 
        }, 
        fix:function(e){ 
            if(e && e.clone) return e;//如果已经处理了,直接返回 
            e = window.event || e;//event是全局变量 
            var fixE = { 
                clone:true, 
                stop:function(){//冒泡 
                    if(e&&e.stopPropagation){ 
                        e.stopPropagation(); 
                    }else{ 
                        e.cancleBubble = true 
                    } 
                }, 
                prevent:function(){//默认动作 
                    if(e && e.preventDefault){ 
                        e.preventDefault(); 
                    }else{ 
                        e.returnValue = false; 
                    } 
                }, 
                target:e.target || e.srcElement, 
                x:e.clientX || e.pageX, 
                Y:e.clientY || e.pageY, 
                //鼠标滚轮事件统一处理 
                wheel:e.wheelDelta/120 || -e.detail/3 
            } 
            return fixE; 
        } 
    } 
    YQ.DOM = { 
        find:function(selector,parentDom){ 
            //do something 
        } 
    }})(window,document); 
简单的分析

代码中的注释还算详细,结合注释就可以看懂,下面我再多说几句,高手飘过,欢迎拍砖…… 
总得来看是个匿名函数,定义了全局变量$(似乎都喜欢美元,如果有喜欢的人民币的,下次加上),函数里面有个YQ的对象,有很多function,包括一些私有的。

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

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

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

基本就这些了,今天就先说核心的部分,其实通过这段代码已经很清晰的了解到这个框架的思想了,后续继续给力的coding,补充扩展…… 
目前为止,框架不到800行代码,包括了常见的jQuery方法,压缩后不到9k,gzip 4.5K~

查看更多:

http://www.huiyi8.com/jiaoben/

http://www.huiyi8.com/js/css/

写的一个轻量级javascript框架的设计模式的更多相关文章

  1. NET Core写了一个轻量级的Interception框架[开源]

    NET Core写了一个轻量级的Interception框架[开源] ASP.NET Core具有一个以ServiceCollection和ServiceProvider为核心的依赖注入框架,虽然这只 ...

  2. 2016 年 50 个最佳的轻量级 JavaScript 框架和库

    作者:IT程序狮链接:https://zhuanlan.zhihu.com/p/24598210来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 回顾今年已发布的 JS ...

  3. 基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇

    基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇 前提 最近对网络编程方面比较有兴趣,在微服务实践上也用到了相对主流的RPC框架如Spring Cloud Gateway底层也切换 ...

  4. 基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇

    前提 前置文章: Github Page:<基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> Coding Page:<基于Netty和SpringBoot实现 ...

  5. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client篇

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> 前 ...

  6. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...

  7. 为了支持AOP的编程模式,我为.NET Core写了一个轻量级的Interception框架[开源]

    ASP.NET Core具有一个以ServiceCollection和ServiceProvider为核心的依赖注入框架,虽然这只是一个很轻量级的框架,但是在大部分情况下能够满足我们的需要.不过我觉得 ...

  8. 分享一个CSS+JavaScript框架materializecss

    一.内容: CSS+JavaScript框架materializecss. 二.网址:http://materializecss.com 三.图片:

  9. 2018.2.5 PHP如何写好一个程序用框架

    随着PHP标准和Composer包管理工具的面世,普通开发者撸一个框架已经不再是什么难事了. 无论是路由管理.ORM管理.还是视图渲染都有许许多多优秀的包可以使用.我们就像堆积木一样把这些包用comp ...

随机推荐

  1. 计划任务cron,date,时间同步ntp,chrony

    取出磁盘利用率最大值 ,写个脚本,做判断,只要快满了,就报警 计划周期性执行的任务提交给crond,到指定时间会自动运行 系统cron任务:系统维护作业  /etc/crontab 用户cron任务: ...

  2. 最全面的C/C++编码规范总结

    C语言是面向过程的,而C++是面向对象的 对于不同的编程语言来说,具体的编码规范可以有很大的不同,但是其宗旨都是一致的,就是保证代码在高质量完成需求的同时具备良好的可读性.可维护性.例如我们可以规定某 ...

  3. java代码开启关闭线程(nginx)

    源码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; pub ...

  4. 获取 AppStore 中 应用 的 IPA 包文件(Mac OS 13+)

    在 Mac OS 12.7 之前,可以通过 iTunes 直接下载 App Store 中应用的 IPA 包,可以提取其他应用的资源图片,查看信息等操作.之后 苹果 公司禁用了这一功能,不能直接通过 ...

  5. 从数组A中删除在数组B中存在的元素,用C语言实现

    从数组A中删除在数组B中存在的元素,用C语言实现 考验数组操作的能力,C语言的熟练程度. //功能:从数组A中删除在数组B中也存在的数据 //输入:arrA --- 数组A // lenA --- 数 ...

  6. PTA的Python练习题(八)

    从 第3章-15 统计一行文本的单词个数 继续 1. s = input() count=0 for c in s: if c==' ': count=count+1 if c=='.': break ...

  7. 文件目录T位

    场景: 共享目录设置T标志 可以看别人的文件,但不可以删除.修改别人的文件 除非是ROOT,目录的拥有者

  8. 在IDEA中为SpringBoot配置热部署

    版本:IDEA Community 2019.2.2,Spring Boot  2.1.8.RELEASE 流程:pom文件中添加依赖: <dependency> <groupId& ...

  9. Python环境搭建-1 Python介绍

    Python翻译成汉语是蟒蛇的意思,并且Python的logo也是两条缠绕在一起的蟒蛇的样子,然而Python语言和蟒蛇实际上并没有一毛钱关系. Python语言是由荷兰程序员Guido van Ro ...

  10. Java中正确使用hashCode和equals方法

    在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...