成品:點(diǎn)我
源碼:點(diǎn)這個(gè)我
需求如下:
let items = $('li')
// 使用$方法傳入選擇器内地,可以返回一個(gè)內(nèi)容為元素節(jié)點(diǎn)的數(shù)組
items.on('click', function(){
console.log('click')
})
// 返回的items 對(duì)象有一個(gè)on方法可以傳入事件和監(jiān)聽(tīng)事件回調(diào)的方法
items.addClass('hi').removeClass('error')
// 新增一個(gè)addClass 和 removeClass方法,并且可以鏈?zhǔn)秸{(diào)用
items.text('你好')
// 為數(shù)組里面每個(gè)item 寫(xiě)入text
items.text()
// 返回內(nèi)容
item = $(items.get(0))
// 1. item 沒(méi)有 siblings 方法
// 2. 需求要有 xxx.siblings 方法
// 3. $item = $(item) $item.siblings() 返回 item 的兄弟
// 1. $item.siblings() 沒(méi)有 addClass 方法
// 2. 需求要有 $item.siblings().addClass
// 3. $item.siblings() 的結(jié)果是 $('li') 類(lèi)似的東西
$item.siblings().removeClass('active').end()
.addClass('active')
- 第一個(gè)需求赋除,需要我們通過(guò)$方法傳入一個(gè)需要查詢(xún)的選擇器阱缓,并使它返回一個(gè)包含查詢(xún)到結(jié)果的數(shù)組,這個(gè)數(shù)組里面是元素和節(jié)點(diǎn):
window.$ = function (selectorOrNode) {
let array = []
let items = document.querySelectorAll(selectorOrNode)
for (var i = 0; i < items.length; i++) {
array.push(items[i])
}
return array
}
- 返回的items 對(duì)象有一個(gè)on方法可以傳入事件和監(jiān)聽(tīng)事件回調(diào)的方法
array.on = function(eventType, fnc){
for(var i = 0; i < items.length; i++){
array[i].addEventListener(eventType, fnc)
}
}
- 新增一個(gè)addClass 和 removeClass方法举农,并且可以鏈?zhǔn)秸{(diào)用
array.addClass = function (value) {
for (var i = 0; i < array.length; i++) {
array[i].classList.add(value)
}
return array
}
array.removeClass = function (value) {
for (var i = 0; i < array.length; i++) {
array[i].classList.remove(value)
}
return array
}
這里還有兩個(gè)問(wèn)題荆针,如果傳值為空,會(huì)傳入一個(gè)undefined 作為參數(shù)颁糟,此時(shí)不應(yīng)該給原數(shù)組做任何操作航背,我們修改一下:
array.addClass = function (className) {
if (className !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].classList.add(className)
}
}
return array
}
array.removeClass = function (className) {
if (className !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].classList.remove(className)
}
}
return array
}
- 新增一個(gè)text方法,用于修改數(shù)組里面元素的內(nèi)容棱貌,同時(shí)當(dāng)不傳值時(shí)玖媚,以數(shù)組形式返回里面的內(nèi)容,這里有2個(gè)問(wèn)題:
- 如果使用contentText的方法會(huì)將元素內(nèi)所有內(nèi)容覆蓋键畴,尋找是否有其他方法最盅,或者新建不同的方法用來(lái)區(qū)別用途,否則該方法只適用于沒(méi)有子元素的元素
- 返回的不是原數(shù)組
array.text = function (text) {
if (text !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].textContent = text //這個(gè)方法有局限
}
return array
}else{
let result = []
for(var i =0; i< array.length;i++){
result.push(array[i].textContent)
}
return result
}
}
- 下一個(gè)需求起惕,如果傳入的是一個(gè)元素/或者節(jié)點(diǎn)涡贱,此時(shí)需要返回包含這個(gè)元素的數(shù)組,且可以調(diào)用前面的方法惹想,或者傳入的是一個(gè)數(shù)組问词,則將每個(gè)數(shù)組里面如果是元素的部分組成新的數(shù)組,用于調(diào)用$里面數(shù)組的方法:
window.$ = function (selectorOrNode) {
let array = []
if (typeof selectorOrNode === 'string') {
let items = document.querySelectorAll(selectorOrNode)
for (var i = 0; i < items.length; i++) {
array.push(items[i])
}
} else if (selectorOrNode instanceof Element) {
array.push(selectorOrNode)
} else if (selectorOrNode instanceof Array) {
for (var i = 0; i < selectorOrNode.length; i++) {
if (selectorOrNode[i] instanceof Element) {
array.push(selectorOrNode[i])
}
}
}
array.on = function (eventType, fnc) {
for (var i = 0; i < array.length; i++) {
array[i].addEventListener(eventType, fnc)
}
return array
}
array.addClass = function (className) {
if (className !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].classList.add(className)
}
}
return array
}
array.removeClass = function (className) {
if (className !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].classList.remove(className)
}
}
return array
}
array.text = function (text) {
if (text !== undefined) {
for (var i = 0; i < array.length; i++) {
array[i].textContent = text
}
return array
} else {
let result = []
for (var i = 0; i < array.length; i++) {
result.push(array[i].textContent)
}
return result
}
}
return array
}
- 再加一個(gè)get方法獲取數(shù)組中的子元素:
array.get = function(index){
return array[index]
}
- 新增獲取一個(gè)元素的兄弟元素的方法sibling()嘀粱,且可以鏈?zhǔn)秸{(diào)用子方法end()返回原數(shù)組:
array.siblings = function(){
let sibling = array[0].parentNode.children
// 該方法只用作判斷元素的兄弟姐妹激挪,所以傳入的是一個(gè)數(shù)組辰狡,該數(shù)組里面只有一個(gè)元素,即需要判斷兄弟姐妹的那個(gè)元素
let result = []
for(var i = 0 ;i<sibling.length;i++){
if(sibling[i] !== array[0]){
result.push(sibling[i])
}
}
let items = $(result)
// 遞歸保證結(jié)果依然能使用$里面的數(shù)組方法
items.previousSelection = array
// 附加一個(gè)屬性為執(zhí)行該方法前的數(shù)組垄分,用于后面的end()方法返回原數(shù)組
return items
}
array.end = function (){
return array.previousSelection
}
學(xué)習(xí)過(guò)程中遇到的問(wèn)題:
- for循環(huán)遍歷時(shí)宛篇,addClass,on薄湿,removeClass方法都用錯(cuò)了長(zhǎng)度叫倍,用了item.length,導(dǎo)致出現(xiàn)了bug豺瘤,再比對(duì)老師的原代碼時(shí)才發(fā)現(xiàn)吆倦,反映了光模仿代碼也是會(huì)出問(wèn)題的,謹(jǐn)記謹(jǐn)記坐求。