window.jQuery()是我们提供的全局函数
特殊函数jQuery:jQuery(选择器)用于获取对应的元素,但是它却不返回这些元素,相反它返回一个对象,称为jQuery构造出来的对象(API),这个对象可以操作对用的元素
那么jQuery是构造函数吗:jQuery不是常规意义上的构造函数,它不需要加new,这是因为应用了某些技巧
HTML
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>手写 JQuery</title>
</head>
<body>
<div class="test1">
<div class="child">child1</div>
<div class="child">child2</div>
<div class="child">child3</div>
</div>
<div class="test2">你好</div>
<div class="test3">你好</div>
<script src="jquery.js"></script>
<script src="main.js"></script>
</body>
</html>
jQuery.js
window.jQuery = function (selectorOrArray) {
//const elements = document.querySelectorAll(selectorOrArray)//api可以操作elements
let elements
if (typeof selectorOrArray === 'string') {
elements = document.querySelectorAll(selectorOrArray)
} else if (selectorOrArray instanceof Array) {
elements = selectorOrArray
}
const api = {
addClass(className) {//闭包,函数访问外部变量elements
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(className)
}
return api
},
oldAPI: selectorOrArray.oldAPI,//获取数组的oldAPI
find(selector) {
let array = []
for (let i = 0; i < elements.length; i++) {
const elementsList2 = Array.from(elements[i].querySelectorAll(selector))
array = array.concat(elementsList2)
}
array.oldAPI = this //this是 旧api
return jQuery(array)
},
end() {
return this.oldAPI //this是 新api
},
each(fn) { //遍历并对每个元素执行fn
for (let i = 0; i < elements.length; i++) {
fn.call(null, elements[i], i)
}
return this
},
parent(){ //获取爸爸
const array =[]
this.each((node)=>{
array.push(node.parentNode)
})
return jQuery(array)
},
children(){
const array = []
this.each((node)=>{
array.push(...node.children)//将数组里的元素平摊
})
return jQuery(array)
},
}
return api//不返回elements,返回api
}
main.js
//const api = jQuery('.test')//不返回elements,返回api
//api.addClass('red')//遍历所有刚才的元素并添加red
//api.addClass('green').addClass('blue')//链式操作
//jquery文件中8行return api,可以进行链式操作(add green后又返回api所以可以继续.添加)
//const x1=jQuery('.test1').find('.child')//查找元素
//console.log(x1)
const api = jQuery('.test')//设定为api1
const api= api.find('.child').addClass('red').addClass('green')//此api设定为api2
const oldAPI = api.end().addClass('yellow')//这里的api为api2
api.each((div)=>console.log(div))
命名风格
DOM只能用DOM的API
jQuery只能用jQuery的API
所以建议jQuery的API前面加上div2.find