學(xué)習(xí)過(guò)jQuery的原理后疯特,自己手動(dòng)封裝兩個(gè)實(shí)用函數(shù)楞抡,來(lái)更深刻的理解jQuery的實(shí)現(xiàn)過(guò)程
一. 定義一個(gè)命名空間
定義命名空間是為了防止對(duì)DOM的API造成污染
window.lhQuery = {}
二. 封裝一些函數(shù)
把想要實(shí)現(xiàn)的效果,封裝起來(lái),在需要的時(shí)候調(diào)用它
window.lhQuery = {}
lhQuery = function(){
function addClass(){}//添加class名
function setText(){}//修改節(jié)點(diǎn)文本
}
為了達(dá)到j(luò)Query的——$('x').addClass('xxx')——這種效果,至少需要把這些函數(shù)放到一個(gè)對(duì)象中,通過(guò)‘.’來(lái)獲取仙畦。于是做出如下改動(dòng):
window.lhQuery = {}
lhQuery = function(){
let functionObj = {}
functionObj.addClass = function(){}
functionObj.setText= function(){}
return functionObj
}
這樣的話(huà),我們就可以通過(guò)functionObj.addClass()音婶、 functionObj.setText()的方式來(lái)調(diào)用這兩個(gè)函數(shù)
三.獲取必要參數(shù)
DOM操作的主要功能就是對(duì)文檔流中的節(jié)點(diǎn)進(jìn)行各種操作慨畸,所以需要想辦法獲得某個(gè)節(jié)點(diǎn)
window.lhQuery = {}
lhQuery = function(param){ //添加參數(shù)param,以便在調(diào)用lhQuery(param)時(shí)能夠或許想要找到的節(jié)點(diǎn)
let functionObj = {}
if(typeof param === 'string'){ //如果傳遞的參數(shù)是一個(gè)字符串的話(huà)↓
let temp = document.querySelectorAll(param)//那么就獲取全部與它相關(guān)的節(jié)點(diǎn)↓
for(let i = 0; i < temp.length; i++){
functionObj [i] = temp[i] //并存入functionObj中
}
functionObj .length = temp.length //添加長(zhǎng)度key
}else if(param instanceof Node) { //如果傳遞的參數(shù)本身就是一個(gè)節(jié)點(diǎn)
functionObj = {
0: param, //那只需要記住這個(gè)節(jié)點(diǎn)就好了
length: 1
}
}
//如此一來(lái)衣式,lhQuery這個(gè)偽數(shù)組就具有以下兩個(gè)API
functionObj.addClass = function(){}
functionObj.setText= function(){}
return functionObj
}
打印一下此時(shí)functionObj寸士,看看它現(xiàn)在是一個(gè)怎樣的結(jié)構(gòu)
可以看到碴卧,此時(shí)的lhQuery返回的偽數(shù)組有三個(gè)節(jié)點(diǎn)弱卡,分別是0:div; 1:div; 2:div;同時(shí)還有兩個(gè)方法addClass()以及setText()
四. 通過(guò)DOM提供的API去實(shí)現(xiàn)addClass與setText方法
DOM提供的classList.add()的API又長(zhǎng)又難用,所以將這個(gè)API封裝到自己的方法中住册,調(diào)用起來(lái)會(huì)更加舒服婶博。
具體的實(shí)現(xiàn)方法如下
window.lhQuery = {}
lhQuery = function(param){
let functionObj = {}
if(typeof param === 'string'){
let temp = document.querySelectorAll(param)
for(let i = 0; i < temp.length; i++){
functionObj [i] = temp[i]
}
functionObj .length = temp.length
}else if(param instanceof Node) {
functionObj = {
0: param,
length: 1
}
}
//通過(guò)lhQuery(div).addClass('className')傳遞className的參數(shù)
functionObj.addClass = function(className){
for(let i = 0; i < functionObj.length; i++){ //遍歷圖-1的偽數(shù)組,給他們添加className
functionObj[i].classList.add(className)
}
}
//通過(guò)lhQuery(div).textContent ('text')傳遞text的參數(shù)
functionObj.setText= function(text){
for(let i = 0; i < functionObj.length; i++){ //遍歷圖-1的偽數(shù)組荧飞,為他們修改textContent
functionObj[i].textContent = text
}
}
return functionObj
}
五. 小結(jié)
這只是jQuery的基本思路凡人,實(shí)際上jQuery比這個(gè)強(qiáng)大的多的多的多的多,但是只要了解了這個(gè)思路垢箕,去看jQuery的文檔划栓,那應(yīng)該是沒(méi)有任何問(wèn)題了~最后在做一個(gè)小優(yōu)化兑巾,讓lhQuery在使用起來(lái)的時(shí)候看起來(lái)更像jQuery
window.$ = lhQuery
var $div = $('div')
//接下來(lái)条获,就可以肆意妄為啦
$div.addClass('successful')
$div.setText('successful')