构建jQuery框架封装 nextAll 和 prevAll 方法!!!!(超级篇!)

Posted 努力中的小mi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构建jQuery框架封装 nextAll 和 prevAll 方法!!!!(超级篇!)相关的知识,希望对你有一定的参考价值。

闲话🎈

最近在弄 jquery 源码,感觉真的对自己的提升有很大的进步,在jquery框架中也就使用到了原型和原型链,还有闭包的概念,然后各种的思想,什么链式编程,还有extend这个方法非常的nice,然后接下来,我会带着大家写一下,jquery 中的 nextAll 和 prevAll 这两个函数🎈。






第一步:构建一个自己的 jQuery🧨

可能大家有点疑惑 为什么要传入 window 和 undefined。\\L

  1. 传入 window:
    1.1 为了后期压缩代码方便。
    1.2 为了更高效的查找window。

  2. 传入 undefined:
    2.1 为了后期压缩代码方便。
    2.2 因为IE8及以下浏览器可以对undefined进行改变,所以我们要创建一个私有的undefined,以免以后被随意修改。
// 1. 建立一个 IIFE 函数
(function (window,undefined) {
	var mjQuery = function (selector) {
		return new mjQuery.prototype.init(selector);
	};
	// 创建一个自己的 prototype
	mjQuery.prototype = {
	    constructor:mjQuery,
        init: function (selector) {
        	
        }
    }
    // 改变init的原型 使他的原型指向我们的mjQuery的原型。
	mjQuery.prototype.init.prototype = mjQuery.prototype;
	
    window.mjQuery = $ = mjQuery;
})(window)
<script src="xmjQuery.js"></script>
<body>
	<script>
		console.log($()); // 返回 init{};
	</script>
</body>

第二步:编写一些基本结构🎨

为了后期做准备 当我们 $('div‘) 将会获取到div里面所以的元素并将 返回到一个init对象里面 进行操作。

mjQuery.prototype = {
        init: function (selector) {

            if (typeof selector === 'string') {

                // 判断是否为代码片段
                if (selector.charAt(0) == "<" && selector.charAt(selector.length - 1) == ">" && selector.length >= 3) {
                    console.log('选择器')
                }
                // 判断是否为选择器
                else {

                    var dom = document.querySelectorAll(selector);
                    [].push.apply(this, dom);

                }

            }
            // 判断是否为数组
            else if ("length" in selector && typeof selector == 'object' && selector != window) {

                // 1. 转真数组
                var arr = [].slice.call(selector);
                // 2. 转伪数组
                [].push.apply(this, arr);

            }
            return this;
        }
    }
<script src="xmjQuery.js"></script>
<body>
	<div></div>
	<script>
		console.log($('div')); // 返回一个init {0:div,length:1};
	</script>
</body>

第三步:编写 nextAll 方法🎃🎀

一个很牛逼的技巧 mjQuery.extend({}) 和 mjQuery.prototype.extend({}) 这样可以让我们的后期维护变得更加的方便。


mjQuery.prototype.extend = mjQuery.extend = function (obj) {
        for (var k in obj) {
           // this相当于 mjquery 或 mjquery.prototype 看谁调用了
            this[k] = obj[k];
       	}
}

// 将方法写到了 xmjQuery的原型上。
mjQuery.prototype.extend({
        nextAll: function (name) {
            var res = [];
            // 临时存储数组
            var tempArr = [];
            // 临时存储数组2 
            var tempArr2 = [];
            // 临时存储索引值
            var tempIndex = 0;

            // 没有没有传入参数的时候
            if (arguments.length == 0) {
                var sc = document.body.querySelector('script');

                // 1. 遍历查找的第一个this 
                for (var i = 0; i < this.length; i++) {
                	if (i == 0) {
						// 2. 找到第一个this的父元素
	                    var parent = this[i].parentNode;
	                    // 2.1 遍历父元素里面的子元素
	                    for (var j = 0; j < parent.children.length; j++) {
	                        // 3. 判断当前父元素里面的子元素 是否 和 this 这个值不相等
	                        if (parent.children[j] != this[i] && parent.children[j] != sc) {
	                            tempArr.push(parent.children[j]);
	                        }
	                        // 4. 如果相等拿到他的索引值
	                        else {
	                            if (parent.children[j] == this[i]) {
	                                tempIndex = j;
	                            }
	                        }
	                    }

					}
                    
                }
                // 5. 判断把拿到索引值的前面内容都 咔嚓掉
                for (var i = 0; i < tempArr.length; i++) {
                    if (i < tempIndex) {
                        // 6. 将完整的数组传入 res 里面去
                        res.push(tempArr[i]);
                    }
                }
            }
            // 传入参数
            else {
                var sc = document.body.querySelector('script');

                // 1. 遍历查找的第一个this 
                for (var i = 0; i < this.length; i++) {
                	if (i == 0) {
						// 2. 找到第一个this的父元素
	                    var parent = this[0].parentNode;
	                    // 2.1 遍历父元素里面的子元素
	                    for (var j = 0; j < parent.children.length; j++) {
	                        // 3. 判断当前父元素里面的子元素 是否 和 this 这个值不相等
	                        if (parent.children[j] != this[i] && parent.children[j] != sc) {
	                            tempArr.push(parent.children[j]);
	                        }
	                        // 4. 如果相等拿到他的索引值
	                        else {
	                            if (parent.children[j] == this[i]) {
	                                tempIndex = j;
	                            }
	                        }
	                    }
					}
                    
                }
                // 5. 判断把拿到索引值的前面内容都 咔嚓掉
                for (var i = 0; i < tempArr.length; i++) {
                    if (i >= tempIndex) {
                        // 6. 将完整的数组传入 res 里面去
                        tempArr2.push(tempArr[i]);
                    }
                }

                // 7. 判断完整数组里面是否有 传入name的元素
                for (var i = 0; i < tempArr2.length; i++) {
                    var e = document.querySelectorAll(name);
                    for (var j = 0; j < e.length; j++) {
                        if (tempArr2[i] == e[j]) {
                            res.push(tempArr2[i]);
                        }
                    }
                }
            }
            return $(res);


        }
    })
<script src="mjQuery.js"></script>
<body>
    <div class="box1"></div>
    <div class="box1"></div>
    <div class="box1"></div>
    <div class="box2"></div>
    <p class="next"></p>
    <div class="box2">
        <!-- <div class="box1"></div>
        <p class="next"></p>
        <div class="box1"></div>
        <div class="box1"></div> -->
    </div>
    <div class="box2"></div>
    <p class="next"></p>
    <p class="next"></p>
    <div class="box2"></div>
    <div id="box2"></div>
    <div class="box3">
        <div class="box2"></div>
    </div>
    <div class="box2"></div>
    <script>
        console.log($('.next').nextAll('.box2')); // init {0: div.box2, 1: div.box2, 2: div.box2, 3: div.box2, length: 4}
    </script>
</body>

第四步:编写 prveAll 方法🎇

mjQuery.prototype.extend({
        prevAll: function (name) {
            var res = [];
            // 临时存储数组
            var tempArr = [];
            // 临时存储数组2 
            var tempArr2 = [];
            // 临时存储索引值
            var tempIndex = 0;

            // 没有没有传入参数的时候
            if (arguments.length == 0) {
                var sc = document.body.querySelector('script');

                // 1. 遍历查找的第一个this 
                for (var i = 0; i < this.length; i++) {
                    // 2. 找到第一个this的父元素
                    if (i == 0) {
                        var parent = this[i].parentNode;
                        // 2.1 遍历父元素里面的子元素
                        for (var j = 0; j < parent.children.length; j++) {
                            // 3. 判断当前父元素里面的子元素 是否 和 this 这个值不相等
                            if (parent.children[j] != this[i] && parent.children[j] != sc) {
                                tempArr.push(parent.children[j]);
                            }
                            // 4. 如果相等拿到他的索引值
                            else {
                                if (parent.children[j] == this[i]) {
                                    tempIndex = j;
                                }
                            }
                        }
                    }


                }
                // 5. 判断把拿到索引值的前面内容都 咔嚓掉
                for (var i = 0; i < tempArr.length; i++) {
                    if (i < tempIndex) {
                        // 6. 将完整的数组传入 res 里面去
                        res.push(tempArr[i]);
                    }
                }
            }
            // 传入参数
            else {
                var sc = document.body.querySelector('script');

                // 1. 遍历查找的第一个this 
                for (var i = 0; i < this.length; i++) {
                    if (i == 0) {
                        // 2. 找到第一个this的父元素
                        var parent = this[i].parentNode;
                        // 2.1 遍历父元素里面的子元素
                        for (var j = 0; j < parent.children.length; j++) {
                            // 3. 判断当前父元素里面的子元素 是否 和 this 这个值不相等
                            if (parent.children[j] != this[i] && parent.children[j] != sc) {
                                tempArr.push(parent.children[j]);
                            }
                            // 4. 如果相等拿到他的索引值
                            else {
                                if (parent.children[j] == this[i]) {
                                    tempIndex = j;
                                }
                            }
                        }
                    }

                }
                // 5. 判断把拿到索引值的前面内容都 咔嚓掉
                for (var i = 0; i < tempArr.length; i++) {
                    if (i < tempIndex) {
                        // 6. 将完整的数组传入 res 里面去
                        tempArr2.push(tempArr[i]);
                    }
                }

                // 7. 判断完整数组里面是否有 传入name的元素
                for (var i = 0; i < tempArr2.length; i++) {
                    var e = document.querySelectorAll(name);
                    for (var j = 0; j < e.length; j++) {
                        if (tempArr2[i] == e[j]) {
                            res.push(tempArr2[i]);
                        }
                    }
                }
            }
            return $(res);


        },
        
    })
<script src="mjQuery.js"></script>
<body>
    <div class="box1"></div>
    <div class="box1"></div>
    <div class="box1"></div>
    <div class="box2"></div>
    <p class="next"></p>
    <div class="box2">
        <!-- <div class="box1"></div>
        <p class="next"></p>
        <div class="box1"></div>
        <div class="box1"></div> -->
    </div>
    jQuery Keydown Next、NextAll、父问题

jquery nextAll() 与 prevAll()

nextAll() 中的回调函数

jquery nextAll() 函数,检查是不是有next

常用Javascript代码片段集锦

jQuery中事件模块介绍