一办素、為什么會(huì)出現(xiàn)jQuery呢角雷?
客觀原因:原生JS的API有很多的不便,DOM的API尤其反人類性穿,所以這一期就從DOM API講起
主觀原因:懶勺三、為了更加效率
二、原生的DOM API 我們要達(dá)到“獲取所有的同類元素需曾,并給他們加上同一個(gè)樣式”需求怎么辦呢吗坚?
html代碼:
<body>
<ul>
<li>第1個(gè)</li>
<li>第2個(gè)</li>
<li>第3個(gè)</li>
<li>第4個(gè)</li>
<li>第5個(gè)</li>
</ul>
</body>
1、獲取所有的li
元素
var lies = document.querySelectorAll('ul > li')
2呆万、給所有的li
元素加上一個(gè)class
首先document.querySelectorAll()這個(gè)API商源,獲取的是一個(gè)NodeList的偽數(shù)組,上面獲取的結(jié)果如下:
所以我們需要遍歷一下谋减,給每個(gè)
li
加上class
for(let i=0; i<lies.length; i++){
lies[i].classList.add(className)
}
然后這個(gè)時(shí)候呢牡彻,我們已經(jīng)用原生JS的API達(dá)到了需求,是不是很麻煩出爹?好吧讨便,其實(shí)也沒(méi)有很麻煩……但是為了更懶充甚,不,是為了更加效率霸褒,我們可以對(duì)他進(jìn)行一系列的改進(jìn)伴找。(PS:有些需求用原生JS真的很麻煩,這就促使了大家為了效率而發(fā)明創(chuàng)造)
三废菱、我想用更簡(jiǎn)短的代碼實(shí)現(xiàn)上述的功能技矮,并且造福同行,如何實(shí)現(xiàn)呢殊轴?
1衰倦、封裝函數(shù)
封裝一個(gè)getNodes()函數(shù)
function getNodes(selector){
var nodes = document.querySelectorAll(selector)
return nodes
}
var lies = getNodes('ul > li')
封裝一個(gè)addClass()函數(shù)
function addClass(node,className){
for(let i=0; i<lies.length; i++){
node[i].classList.add(className)
}
}
addClass(lies,'red')
2、命名空間-給他們加上一個(gè)名字
創(chuàng)建命名空間可以很好的避免全局變量名沖突旁理,什么意思呢樊零,就是我可以叫g(shù)etNodes()、 addClass()孽文,別人也可以啊驻襟,這樣就很容易發(fā)生互相覆蓋和沖突。
window.JRGDOM = {}
JRGDOM.getNodes = function (selector){
var nodes = document.querySelectorAll(selector)
return nodes
}
JRGDOM.addClass = function (node,className){
for(let i=0; i<lies.length; i++){
node[i].classList.add(className)
}
}
var lies = JRGDOM.getNodes('ul > li')
JRGDOM.addClass(lies,'red')
3芋哭、能不能把node放在前面呢
剛才我們都是把node或者選擇器放在函數(shù)的參數(shù)傳進(jìn)去沉衣,是否可以把node放在前面,從而更加的方便呢减牺?
方法一:擴(kuò)展 Node 接口豌习,直接在 Node.prototype 上加函數(shù)
這個(gè)方法會(huì)存在一個(gè)問(wèn)題:可能會(huì)覆蓋原有Node.prototype的函數(shù),而且可能會(huì)互相影響拔疚。
方法二:新的接口 BetterNode肥隆,這是一種無(wú)侵入的方法
window.JRGDOM = function(nodeOrSelector) {
let nodes = {}
if (typeof nodeOrSelector === 'string'){
nodes = document.querySelectorAll(nodeOrSelector)
}else if(nodeOrSelector instanceof Node){
nodes = {
0: nodeOrSelector,
length: 1
}
}
nodes.addClass = function(className){
for(let i=0; i<this.length; i++){
this[i].classList.add(className)
}
}
return nodes
}
var lies = JRGDOM('ul>li')
lies.addClass('red')
4、JRGDOM名字不夠響亮稚失,那就改個(gè)好聽點(diǎn)的名字吧
那就改成把JRGDOM改成jQuery吧巷屿,別問(wèn),問(wèn)就是改成jQuery墩虹。
window.jQuery = function(nodeOrSelector) {
let nodes = {}
……
nodes.addClass = function(){ }
return nodes
}
5嘱巾、jQuery名字是挺響亮的,但是太長(zhǎng)了诫钓,寫起來(lái)有點(diǎn)費(fèi)勁旬昭,那就再改個(gè)縮寫吧 $
window.$ = function(nodeOrSelector) {
let nodes = {}
……
nodes.addClass = function(){ }
return nodes
}
6、這個(gè)時(shí)候我們的需求就可以用一行代碼搞定了
$('ul>li').addClass('red')
菌湃,這里已經(jīng)初具jQuery的雛形了
7问拘、jQuery的改進(jìn)遠(yuǎn)不止如此
1、jQuery 在兼容性方面做得很好,1.7 版本兼容到 IE 6
2骤坐、jQuery 還有動(dòng)畫绪杏、AJAX 等模塊,不止 DOM 操作
3纽绍、jQuery 的功能更豐富
4蕾久、jQuery 其實(shí)使用了 prototype,但這里沒(méi)有使用
結(jié)語(yǔ)
其實(shí)這個(gè)時(shí)候你已經(jīng)了解jQuery了拌夏,簡(jiǎn)單的說(shuō)僧著,jQuery就是一個(gè)封裝好的函數(shù)庫(kù),將原生JS的各種API重新寫成了高效率障簿,高語(yǔ)義化盹愚,高兼容性的API,大大滿足了大家‘懶’的需求站故。
歡迎大家指正文中錯(cuò)誤皆怕,感謝饑人谷,感謝方方老師~