[JavaScript練習(xí)]造個(gè)簡單的DOM庫

成品:點(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)聽事件回調(diào)的方法
items.addClass('hi').removeClass('error')
// 新增一個(gè)addClass 和 removeClass方法,并且可以鏈?zhǔn)秸{(diào)用
items.text('你好')
// 為數(shù)組里面每個(gè)item 寫入text 
items.text() 
// 返回內(nèi)容
item = $(items.get(0))

// 1. item 沒有 siblings 方法
// 2. 需求要有 xxx.siblings 方法
// 3. $item = $(item)   $item.siblings() 返回 item 的兄弟

// 1. $item.siblings() 沒有 addClass 方法
// 2. 需求要有  $item.siblings().addClass
// 3. $item.siblings() 的結(jié)果是 $('li') 類似的東西

$item.siblings().removeClass('active').end()
  .addClass('active')
  • 第一個(gè)需求,需要我們通過$方法傳入一個(gè)需要查詢的選擇器,并使它返回一個(gè)包含查詢到結(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)聽事件回調(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è)問題,如果傳值為空,會(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è)問題:
    1. 如果使用contentText的方法會(huì)將元素內(nèi)所有內(nèi)容覆蓋,尋找是否有其他方法,或者新建不同的方法用來區(qū)別用途,否則該方法只適用于沒有子元素的元素
    2. 返回的不是原數(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í)過程中遇到的問題:

  • for循環(huán)遍歷時(shí),addClass,on,removeClass方法都用錯(cuò)了長度,用了item.length,導(dǎo)致出現(xiàn)了bug,再比對(duì)老師的原代碼時(shí)才發(fā)現(xiàn),反映了光模仿代碼也是會(huì)出問題的,謹(jǐn)記謹(jǐn)記。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、樣式篇 第1章 初識(shí)jQuery (1)環(huán)境搭建 進(jìn)入官方網(wǎng)站獲取最新的版本 http://jquery.co...
    凜0_0閱讀 3,662評(píng)論 0 44
  • 第一章 入門 基本功能:訪問和操作 dom 元素,控制頁面樣式,對(duì)頁面的事件處理,與ajax完美結(jié)合,有豐富的插件...
    X_Arts閱讀 1,138評(píng)論 0 2
  • 2017.7.21 6M23D 西紅柿中含有豐富的維生素、礦物質(zhì)...
    梓辰麻麻閱讀 186評(píng)論 0 0
  • 一早趕到派出所,領(lǐng)到新的身份證,有效期拉長到20年了,下一次換證,應(yīng)該是我成為一個(gè)退休大媽的時(shí)候,從奔四變成...
    米修米修嗶哩嗶哩閱讀 175評(píng)論 0 0
  • 讀《少年維特的煩惱》,激起了心底深處很多的回憶,那回憶不僅有畫面,還充盈著當(dāng)時(shí)的感受和心情,非常的強(qiáng)烈而又那么清晰...
    喜氣襲人閱讀 422評(píng)論 1 2

友情鏈接更多精彩內(nèi)容