前言
马上就快到2022年了,jQuery已然过时,那我们新人是否还有学习jQuery的必要呢?
我认为是有的,因为jQuery中也蕴含了很多编程套路,我们新人应该学习一些jQuery的思想,它可以作为一个过渡,帮助我们更好地理解Vue和React等更为复杂的框架
设计思想
我们知道,jQuery的基本设计思想和主要用法,就是"选择某个网页元素,然后对其进行某种操作"。
展开来讲就是:提供一个函数,这个函数接受一个选择器(或数组),根据这个选择器获取一些元素,然后返回一个对象(我们称为api),这个对象有一些方法可以操作这些元素。
根据这个思想,我们就可以简单地写出一个丐版jQuery
window.$ = window.jQuery = function(selectorOrArray){
let elements
if(typeof selectorOrArray ==='string'){
elements = document.querySelectorAll(selectorOrArray)
}else if(selectorOrArray instanceof Array){
elements = selectorOrArray
}
let api = {
addClass(className){
for(let i=0;i<elements.length;i++){
elements[i].classList.add(className)
}
return this
},
find(selector){
let array = []
for(let i=0;i<elements.length;i++){
const elements2 = Array.from(elements[i].querySelectorAll(selector))//新建一个elements2等于把遍历到的元素组成的数组
array = array.concat(elements2)//把elements2放入空数组
}
array.oldApi = this //this是旧api,这个oldApi只是放在数组里面,所以需要添加oldApi:selectorOrArray.oldApi,让它可以放在选择器或数组里面
return jQuery(array)//新建一个Api对象,让jQuery接受数组,新的Api来操作这个数组
},
oldApi:selectorOrArray.oldApi,
end(){
......
},
each(fn){
......
}
}
return api
}
光是通过这段简短代码,就能够体现jQuery的两个核心设计思想
闭包
这里的addClass和find函数访问了外部的变量elements,这样的好处是:
用户永远不能直接操作elements只能用过函数操作elements,只要函数不死,elements就不会死,因为这个函数在访问elements,被访问的东西是不能随便删掉的
链式调用
(以下jQuery()均写为$)
上述代码中是通过addClass的return this
(这个this就是api),来实现这个操作
它有什么用途?
$('div').find('h3').eq(2).html('Hello');
//找到所有的div元素,在div元素了找到h3标签,选择第三个h3标签,替换文本内容
可以看到,这样连起来调用的方式就称为链式调用,它在下次调用函数时,新的函数包含了上一个函数返回的值,所以它可以把不同的操作连在一起
不仅如此,jQuery还提供了一个end方法,使得结果集可以返回上一步
$('div')
.find('h3')
.eq(2)
.html('Hello')
.end() //退回到选中所有的h3元素的那一步
.eq(0) //选中第一个h3元素
.html('World'); //将它的内容改为World
jQuery还有很多其他的设计思想,如:
getter/setter
$('h1').html(); //html()没有参数,表示取出h1的值
$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值
重载
运用函数的重载,一个函数可以同时处理多个不同的参数
如,$()的参数不能可以是选择器,还可以是html标签等
$('.red')
$('<div><span>你好<span></div>')
其余设计思想,请看阮一峰老师的博客:jQuery设计思想
学习这些设计思想,可以让我们学会很多编程技巧,帮助我们自己造轮子,而不是只会一味的调用其他库或框架提供的功能
常见的API
获取元素
表达式可以是CSS选择器:
$(document)
选择整个文档对象$('#myId')
选择ID为myId的网页元素$('div.myClass')
选择class为myClass的div元素$('input[name=first]')
选择name属性等于first的input元素- ......
也可以是jQuery特有的表达式
$('a:first')
选择网页中第一个a元素$('tr:odd')
选择表格的奇数行$('#myForm :input')
选择表单中的input元素$('div:visible')
选择可见的div元素- ......
增
$('.inner').append('<p>Test</p>')
- 在所有class为inner的元素最后面添加一个p标签,简单来说,就是用来添加老幺
$('<p>Test</p>').appendTo('.inner')
- 作用与append相同,但是语法顺序不同
$('.inner').prepend('<p>Test</p>')
- 在所有class为inner的元素最前面添加一个p标签,简单来说,就是用来添加老大
$('<p>Test</p>').prependTo('.inner')
- 作用与prepend相同,语法不同
$('<div/>').after('<p>Test</p>')
和$('<p>Test</p>').insertAfter('.inner')
- 作用与append,appendTo相同
('<div/>').before('<p>Test</p>')
和$('<p>Test</p>').insertBefore('.inner')
- 作用与prepend,prepend相同
删
$('.hello').empty()
- 删除class为hello里的所有子节点
$('.hello').remove()
- 删除class为hello的元素,如果hello里面包含子节点,子节点同样会被移除
$('div').remove('.hello')
- 添加一个可选的选择器参数来过滤匹配的元素,删除div里面class为hello的元素
改和查
-
$('div').insertAfter($('p'))
- 如果div和p都是现有元素,那么这个方法可以把div移到p后面
$('p').after($('div'))
也可以实现这个操作- 它们的不同就是返回的元素不一样,第一种返回的是div,第二种是p
- 同样地,在增操作里的所有API都可以实现这样的移动功能
-
读写内容
$('h1').html(); //html()没有参数,表示取出h1的值
$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值
类似地,取值和赋值函数有:
.html() 取出或设置html内容
.text() 取出或设置text内容
.attr() 取出或设置某个属性的值
......
- 读写CSS
//读
$(div).css("background-color") 读取div的背景色
$(div).css(["width", "height", "color", "background-color"]) 读取div的多个属性值
//写
$(div).css("color","red") 更改div的颜色
$(div).css({'background-color' : 'yellow', 'font-weight' : 'bolder'}) 更改div的多个属性值
$(div).on('click', fn)
- 给div添加一个名为click的监听事件
$(div).off('click', fn)
- 删除这个监听事件
完整API 请参考:jQuery_API中文文档