构建jQuery框架封装 nextAll 和 prevAll 方法!!!!(超级篇!)
Posted 努力中的小mi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构建jQuery框架封装 nextAll 和 prevAll 方法!!!!(超级篇!)相关的知识,希望对你有一定的参考价值。
闲话🎈
最近在弄 jquery 源码,感觉真的对自己的提升有很大的进步,在jquery框架中也就使用到了原型和原型链,还有闭包的概念,然后各种的思想,什么链式编程,还有extend这个方法非常的nice,然后接下来,我会带着大家写一下,jquery 中的 nextAll 和 prevAll 这两个函数🎈。
第一步:构建一个自己的 jQuery🧨
可能大家有点疑惑 为什么要传入 window 和 undefined。\\L
- 传入 window:
1.1 为了后期压缩代码方便。
1.2 为了更高效的查找window。
- 传入 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、父问题