结合阮一峰的jQuery设计思路,自己写一个简单的jQuery
代码放最后
jQuery的设计思路
1. 选取网页内元素
选取网页内某一元素,对其进行操作。
jQuery()获取对应的元素,但它不返回这些元素,
返回一个对象称为api, 这个对象可以直接操作对应的元素
window.$ = window.jQuery;
$(document) //选择整个文档对象
$('#myId') //选择ID为myId的网页元素
$('div.myClass') // 选择class为myClass的div元素
$('input[name=first]') // 选择name属性等于first的input元素
2. 链式调用
每一步的jQuery操作,返回的都是一个当前所操作的jQuery对象,所以不同操作可以连在一起。
3. getter和setter模式
使用同一个函数,来完成取值(getter)和赋值(setter),即"取值器"与"赋值器"合一。到底是取值还是赋值,由函数的参数决定
$('h1').html(); //html()没有参数,表示取出h1的值
$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值
4.重载
对于统一个属性传入不同的参数,运用重载可以的得到不同的作用效果。
元素的一些操作
增
遍历
5. 代码
window.$ = window.jQuery;
window.jQuery = function (selectorOrArrayOrTemplate) {
let elements;
//重载
if (typeof selectorOrArrayOrTemplate === "string") {
if (selectorOrArrayOrTemplate[0] === "<") {
// 创建 div
elements = [createElement(selectorOrArrayOrTemplate)];
} else {
// 查找 div
elements = document.querySelectorAll(selectorOrArrayOrTemplate);
}
} else if (selectorOrArrayOrTemplate instanceof Array) {
elements = selectorOrArrayOrTemplate;
}
function createElement(string) {
const container = document.createElement("template");
container.innerHTML = string.trim();
return container.content.firstChild;
}
// 闭包 api 可以操作elements
return {
jquery: true,
elements: elements,
oldApi: selectorOrArrayOrTemplate.oldApi,
get(index) {
return elements[index];
},
//添加到某个节点
appendTo(node) {
if (node instanceof Element) {
this.each((el) => node.appendChild(el)); // 遍历 elements,对每个 el 进行 node.appendChild 操作
} else if (node.jquery === true) {
this.each((el) => node.get(0).appendChild(el)); // 遍历 elements,对每个 el 进行 node.get(0).appendChild(el)) 操作
}
},
//添加
append(children) {
if (children instanceof Element) {
this.get(0).appendChild(children);
} else if (children instanceof HTMLCollection) {
for (let i = 0; i < children.length; i++) {
this.get(0).appendChild(children[i]);
}
} else if (children.jquery === true) {
children.each((node) => this.get(0).appendChild(node));
}
},
//查找
find(selector) {
let array = [];
for (let i = 0; i < elements.length; i++) {
const elements2 = Array.from(elements[i].querySelectorAll(selector));
array = array.concat(elements2);
}
array.oldApi = this; // this 就是 旧 api
return jQuery(array);
},
// 遍历
each(fn) {
for (let i = 0; i < elements.length; i++) {
fn.call(null, elements[i], i);
}
return this;
},
//获取父代
parent() {
const array = [];
this.each((node) => {
if (array.indexOf(node.parentNode) === -1) {
array.push(node.parentNode);
}
});
return jQuery(array);
},
//获取子代
children() {
const array = [];
this.each((node) => {
array.push(...node.children);
});
return jQuery(array);
},
//打印
print() {
console.log(elements);
},
//添加类
addClass(className) {
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
element.classList.add(className);
}
return this;
},
end() {
return this.oldApi; // this 就是新 api
},
};
};