手把手带你实现一个mini版jquery

浏览:136 发布日期:2019/11/05 分类:系统代码
手把手带你实现一个mini版jquery
手写一个mini版jquery我们要实现的功能如下:
1.执行结构
2.amd模块检测
3.整体架构搭建
4.原型方法添加
5.全局方法添加

执行结构与amd模块检测    //amd模块检测
     if (typeof define === 'function' && define.amd){
         define(definition);
     }
     //执行结构
     var $ = jQuery = (function(window,undefined){
        
    })(window)
整体架构搭建    // 对dom集合进行存储,生成jquery对象
    function Query(dom, selector){
        // 通过遍历dom集合,将el注入this实例 => Z函数的实例
        let i, len = dom ? dom.length : 0
        for (i = 0; i < len; i++) this[i] = dom[i]
        this.length = len
        this.selector = selector || ''
        return this;
    }
    // 进行dom查看,同时生成jquery对象
    function Z(elements, selector){
        return Query.call(this, elements, selector)
    }
    // 具体的dom查找
    function qsa(element, selector){
        // 暂时不考虑选择器的其它情况
        return element.querySelectorAll(selector)
    }
     // 得到jquery对象
    return function(nodeSelector){
        let doms = qsa(document, nodeSelector)
        // debugger;
        return new Z(doms, nodeSelector);
    }
原型方法添加   Z.prototype = {
        each(callback){
            // [].every 是es5的数组原型方法,用于循环,返回值为布尔值(循环的内容必须都满足,才会返回true,否则返回false)
            [].every.call(this, function(el, index){
                return callback.call(el, index, el) !== false
            })
        },
        // 查找元素
        find(selector){
            let doms = []
            this.each(function(index, el){
                let childs = this.querySelectorAll(selector);
                doms.push(...childs);
            })
            //为了实现链式操作 返回当前对象
            return new Z(doms, selector);
        },
        //增加样式
        addClass:function (classes){
            let className = classes.split(' ');
             className.forEach(value => {
                 this.each(function(index,el){
                    el.classList.add(value);
                 })
             });
            return this;
        },
        //比较第几个
        eq(i){
            let doms = [];
            this.each(function(index, el){
                if(i == index) {
                    doms.push(this);
                }
            })
             //为了实现链式操作 返回当前对象
            return new Z(doms, this.selector);
        },
        //删除方法
        remove(){
            this.each(function(index, el){
                this.remove();
            })
        }
    }
全局方法添加// 定义全局方法(既可以内部使用)
    function isFunction(value) { return typeof value == "function" }
    function isWindow(obj)     { return obj != null && obj == obj.window }
    function isDocument(obj)   { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }

    function $(nodeSelector){
        let doms = qsa(document, nodeSelector)
        return new Z(doms, nodeSelector);
    }

    // 定义zepto的全局方法(也可以外部使用)
    $.isFunction = isFunction;
    $.isWindow = isWindow;
    $.isDocument = isDocument;
    
    // 得到jquery对象
    return $
完整代码//amd模块检测
if (typeof define === 'function' && define.amd){
     define(definition);
 }
var $ = jQuery = (function(window,undefined){
    // 对dom集合进行存储,生成jquery对象
    function Query(dom, selector){
        // 通过遍历dom集合,将el注入this实例 => Z函数的实例
        let i, len = dom ? dom.length : 0
        for (i = 0; i < len; i++) this[i] = dom[i]
        this.length = len
        this.selector = selector || ''
        return this;
    }
    // 进行dom查看,同时生成jquery对象
    function Z(elements, selector){
        return Query.call(this, elements, selector)
    }
    // 具体的dom查找
    function qsa(element, selector){
        // 暂时不考虑选择器的其它情况
        return element.querySelectorAll(selector)
    }

    Z.prototype = {
        each(callback){
            // [].every 是es5的数组原型方法,用于循环,返回值为布尔值(循环的内容必须都满足,才会返回true,否则返回false)
            [].every.call(this, function(el, index){
                return callback.call(el, index, el) !== false
            })
        },
        find(selector){
            let doms = []
            this.each(function(index, el){
                let childs = this.querySelectorAll(selector);
                doms.push(...childs);
            })
            return new Z(doms, selector);
        },
        addClass:function (classes){
            let className = classes.split(' ');
             className.forEach(value => {
                 this.each(function(index,el){
                    el.classList.add(value);
                 })
             });
            return this;
        },
        eq(i){
            let doms = [];
            this.each(function(index, el){
                if(i == index) {
                    doms.push(this);
                }
            })
            return new Z(doms, this.selector);
        },
        remove(){
            this.each(function(index, el){
                this.remove();
            })
        }
    }

    // 定义全局方法(既可以内部使用)
    function isFunction(value) { return typeof value == "function" }
    function isWindow(obj)     { return obj != null && obj == obj.window }
    function isDocument(obj)   { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }

    function $(nodeSelector){
        let doms = qsa(document, nodeSelector)
        return new Z(doms, nodeSelector);
    }

    // 定义zepto的全局方法(也可以外部使用)
    $.isFunction = isFunction;
    $.isWindow = isWindow;
    $.isDocument = isDocument;
    
    // 得到jquery对象
    return $

})(window)
FAQ
实现的功能,优点,可扩展的地方:
1.给元素增加class
2.链式操作
3.需要什么可以在Z的原型方法里添加
4.jquery对象非常纯净,方法添加以及操作都在Z上
5.全局方法调用
评论( 相关
后面还有条评论,点击查看>>