手把手带你实现一个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.全局方法调用
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35942348/article/details/101270560