jQuery 介绍 📗
jQuery 是一个非常经典的 DOM 库,从 06 年 jQuery 发布之后,至今已经被被广泛使用长达十几年。
至于为什么 jQuery 可以被称之为经典,我想是因为首先他有非常优秀的代码设计,使得整个库使用起来非常简单,也便于理解和学习,其次是因为 DOM 本身非常难以操作,开发者需要一个可以简单使用 DOM 的库,而 jQuery 在这件事情上无疑是当时甚至现在做得最好的。
jQuery 的设计非常有意思,他不会直接返回你所选择的元素的对象,而是返回一个封装了该对象以及操作该对象的 API 的对象,用代码表示大概是这样:
1
2
3
4
5
6
7
8
9
10
|
window.$ = function(selector){
//封装
let elements = document.querySelectorAll(selector)
return {
//返回一个可以操作 elements 的对象,通过闭包保持了该对象的可用性
print:function(){
console.log(elements)
}
}
}
|
jQuery 如何获取元素 📌
很简单,可以通过 css 选择器的方式获取,例如:
1
2
3
4
5
6
7
|
$(document) //选择整个文档对象
$('#myId') //选择ID为myId的网页元素
$('div.myClass') // 选择class为myClass的div元素
$('input[name=first]') // 选择name属性等于first的input元素
|
jQuery 创建元素 🔨
创建新元素的方法非常简单,只要把新元素直接传入jQuery的构造函数就行了:
1
2
3
4
5
|
$('<p>Hello</p>');
$('<li class="new">new list item</li>');
$('ul').append('<li>list item</li>');
|
jQuery 修改元素 🛠️
一般来说我们获取了网页元素,最常见的需求就是取得他们的值或者对他们进行赋值操作。
列举一些常用的 API :
1
2
3
4
5
6
7
8
9
10
11
|
.html() //取出或设置html内容
.text() //取出或设置text内容
.attr() //取出或设置某个属性的值
.width() //取出或设置某个元素的宽度
.height() //取出或设置某个元素的高度
.val() //取出某个表单元素的值
|
值得一提的是 jQuery 的设计思想之一,就是使用同一个函数,来完成取值(getter)和赋值(setter),即"取值器"与"赋值器"合一。到底是取值还是赋值,由函数的参数决定。
至于实现 getter/setter ,我想只要判断参数长度,猜测一下用户行为就可以做到,大概是这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
window.$ = function(selector){
//首先还是封装一下元素
let elements = document.querySelectorAll(selector)
return {
text:function(string){
if(arguments.length === 1){ //如果用户传入的参数不为空,那就是需要添加,即 setter
for (let i = 0; i < elements.length; i++) {
elements[i].textContent = string
}
}else if(arguments.length === 0){ //如果用户没有传入参数,那就是需要获取元素的文本内容,即 getter
let arr = []
for (let i = 0; i < elements.length; i++) {
elements[i].textContent = string
arr.push(elements[i].textContent)
}
return arr
}
}
}
}
|
jQuery 复制、删除元素 🗑️
复制元素:
删除元素:
1
2
3
|
.remove() //不保留被删除元素的事件
.detach() //保留被删除元素的事件
|
jQuery 的链式操作是如何实现的 🔫
jQuery 的链式操作可以方便地实现一些更复杂的 DOM 操作,例如:
1
|
$("#div1").find("#child").html("hello")
|
这种链式操作看似很简单,但仔细想的话会发现不太对劲,因为根据前面所说,jQuery 会将用户第一次获取的元素(在这里是div1)封装,然后返回一个可以操作 div1 的对象,而我们的需求却是使用 find 函数找到 div1 的子元素 #child,再对 #child 做操作,所以实际上要实现这种链式操作,还必须要在刚才的基础上再加一层封装,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
window.$ = function(selectorOrArray){
//封装
let elements
//判断一下参数类型
if(typeof selectorOrArray === "string"){
//如果是字符串,代表是用户传入的选择器
elements = document.querySelectorAll(selectorOrArray)
}else if(selectorOrArray instanceof Array){
//如果是数组,代表是用户传入的可能是子元素集合
elements = selectorOrArray
}
return {
//返回一个可以操作 elements 的对象,通过闭包保持了该对象的可用性
print:function(){
console.log(elements)
},
find:function(selector){
//声明一个数组存放子元素
let arr = []
for (let i = 0; i < elements.length; i++) {
arr.push(...elements[i].querySelectorAll(selector))
}
//返回一个新的,可操作封装了子元素的对象
return $(arr)
}
}
}
|
参考
jQuery设计思想 - 阮一峰