成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

掌控 DOM - 它不像你想的那么難

Reducto / 663人閱讀

摘要:很多開發(fā)者認(rèn)為是真的很難或者很慢以至于你需要一個巨大的框架才能讓它服帖。如果我告訴你其實(shí)沒那么復(fù)雜,你信嗎并不難并且它也不慢。它很聰明的和已經(jīng)附加在的元素進(jìn)行比較并按需進(jìn)行插入移除重排等操作

很多開發(fā)者認(rèn)為 DOM 是真的很難(或者很慢)以至于你需要一個巨大的框架才能讓它服帖。于是他們投入了大量的時間去學(xué)習(xí)這些框架。一兩年過去了,又一個框架火了于是你不得不扔掉之前的框架從頭學(xué)起。這樣的事情多重復(fù)幾次就能讓你對 JavaScript 產(chǎn)生疲勞,更不用說那多的數(shù)不過來的依賴。

如果我告訴你 DOM 其實(shí)沒那么復(fù)雜,你信嗎?

DOM 并不難并且它也不慢。

創(chuàng)建元素

要創(chuàng)建一個元素,你只需要寫 document.createElement(tagName)

const h1 = document.createElement("h1")

// 

修改文本內(nèi)容

HTML 元素如果沒有任何內(nèi)容,那就是空的,讓我們用 element.textContent 來增加一些文本

h1.textContent = "Hello world!"

// 

Hello world!

屬性

要定義一個 HTML 元素的屬性,你可以用 element.setAttribute(name, value)

h1.setAttribute("class", "hello")

// 

Hello world!

若要管理 class 有一個 element.className 屬性

h1.className = "hello"

// 

Hello world!

但是,最好的方式是使用 classList

h1.classList.add("hello")

// 

Hello world!

h1.classList.remove("hello") //

Hello world!

要設(shè)置一個元素的 ID,你可以使用標(biāo)簽屬性或者 id 屬性

h1.setAttribute("id", "hello-world")

h1.id = "hello-world"

// 

Hello world!

如果你不確定用標(biāo)簽屬性(attributes)還是對象屬性(properties),就用標(biāo)簽屬性 (表單元素的狀態(tài)除外,如 value 和 checked)

注意,有些布爾值的修改不能使用 element.setAttribute(someBoolean, false),下面這些則可以

input.checked = true

// 

input.checked = false

// 

input.setAttribute(‘checked’, ‘’)

// 

input.removeAttribute("checked")
// 
元素附加

HTML 是結(jié)構(gòu)化的??梢酝ㄟ^ parent.appendChild(child) 來實(shí)現(xiàn)元素附加

document.body.appendChild(h1)

// 

Hello world!

元素移除

有時候你希望去掉一個元素,那么你可以使用 parent.removeChild(child)

document.body.removeChild(h1)

// 
元素查找

你可以使用下列方法來查找子元素

document.getElementById(id)

element.childNodes[i]

element.firstChild === element.childNodes[0]

element.lastChild === element.childNodes[element.childNodes.length - 1]

element.getElementsByTagName(tagName)

element.getElementsByClassName(className)

element.querySelector(query)

element.querySelectorAll(query)

注意 getElementsByTagName, getElementsByClassName 和 querySelectorAll 返回的不是數(shù)組,而是 NodeList,你不能通過 ES5 的數(shù)組快速訪問方式來迭代。

元素間插入元素

想要將元素查到另一個元素的前面?試試 parent.insertBefore(child, before)

/*

 *  

 *    

 *  

 */

document.body.insertBefore(h1, document.body.firstChild)

/*  

 *    

Hello world!

* * */
創(chuàng)建元素列表

如果我們有一些數(shù)據(jù),可以很容易的動態(tài)創(chuàng)建元素。

const data = [
  [ 1, 2, 3 ],
  [ 4, 5, 6 ],
  [ 7, 8, 9 ]
]
const table = document.createElement("table")

data.forEach(row => {
  const tr = document.createElement("tr")

  row.forEach(cell => {
    const td = document.createElement("td")

    td.textContent = cell
    tr.appendChild(td)
 })

  table.appendChild(tr)
})

document.body.appendChild(table)

https://jsfiddle.net/pakastin...

更新元素列表

你希望元素保持最新狀態(tài),可以這么做

const table = document.createElement("table")

document.body.appendChild(table)

updateTable(table, [
  [ 1, 2 ],
  [ 3, 4, 5 ],
  [ 6, 7, 8, 9 ]
])

setTimeout(() => {
  updateTable(table, [
    [ 1, 2, 3, 4 ],
    [ 5, 6, 7 ],
    [ 8, 9 ]
  ])
}, 1000)

function updateTable (table, data) {
  const rowLookup = table._lookup || (table._lookup = [])

  setChildren(table, updateRows(rowLookup, data))
}

function updateRows (rowLookup, rows) {
     return rows.map((row, y) => {
    const tr = rowLookup[y] || (rowLookup[y] = document.createElement("tr"))
    const cellLookup = tr._lookup || (tr._lookup = [])

    setChildren(tr, updateCells(cellLookup, row))

    return tr
  })
}

function updateCells (cellLookup, cells) {
     return cells.map((cell, x) => {
    const td = cellLookup[x] || (cellLookup[x] = document.createElement("td"))

    td.textContent = cell

    return td
  })
}

function setChildren (parent, children) {
  let traverse = parent.firstChild

  for (let i = 0; i < children.length; i++) {
    const child = children[i]

    if (child == null) {
      return
    }

    if (child === traverse) {
      traverse = traverse.nextSibling
    } else if (traverse) {
      parent.insertBefore(child, traverse)
    } else {
      parent.appendChild(child)
    }
  }

  while (traverse) {
    const next = traverse.nextSibling

    parent.removeChild(traverse)

    traverse = next
  }
}

https://jsfiddle.net/pakastin...

以上代碼有兩個事情發(fā)生

一個隱藏屬性 element._lookup = [] 用來查找子元素,使用lookup 我們可以復(fù)用DOM中已經(jīng)存在的元素并更新它們。

setChildren(parent, children) 方法能讓你提供一個元素列表。它很聰明的和已經(jīng)附加在 parent的元素進(jìn)行比較并按需進(jìn)行 插入 移除 重排等操作

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91357.html

相關(guān)文章

  • 二十五歲零基礎(chǔ)轉(zhuǎn)行做軟件測試怎么樣?一個過來人的心路歷程送給迷茫的你

    摘要:一個軟件測試在職老人幫你詳細(xì)分析一下。在軟件測試行業(yè),前兩點(diǎn)可以結(jié)合起來說,就是大環(huán)境和前景以及人才缺口的問題。軟件測試屬于互聯(lián)網(wǎng)技術(shù)的一個分支,就是經(jīng)常被提到的行業(yè)。你零基礎(chǔ)轉(zhuǎn)行嗷,良心奉勸你不要自學(xué)。 一個軟件測試在職老人幫你詳細(xì)分析一下。先不說軟件測試領(lǐng)域,你想轉(zhuǎn)行的話,得知道這個行...

    AlienZHOU 評論0 收藏0
  • 和BEM的戰(zhàn)斗:10個常見問題及如何避免

    摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...

    dongfangyiyu 評論0 收藏0
  • 和BEM的戰(zhàn)斗:10個常見問題及如何避免

    摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...

    mumumu 評論0 收藏0
  • 和BEM的戰(zhàn)斗:10個常見問題及如何避免

    摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...

    荊兆峰 評論0 收藏0
  • 學(xué)習(xí)python12小時后,告訴你,學(xué)python真沒你想的那么!

    摘要:列入全國計算機(jī)二級取代,部分城市試點(diǎn),引入高中。建議通過視頻學(xué)習(xí),這樣不但節(jié)省時間,而且效果很好。能否回憶起那個陡峭的學(xué)習(xí)曲線問題越多,學(xué)的越快。出報告每完成一個項(xiàng)目,總結(jié)報告,必不可少。結(jié)構(gòu)化學(xué)習(xí),才是你我需要真正培養(yǎng)的能力。 編程就如同你學(xué)習(xí)開車,即使,你可以一口氣,說出一輛車的全部零部件,以及內(nèi)燃機(jī)進(jìn)氣、壓縮、做功和排氣過程,但你就是不去練如何開車,怎么上路。你確定,你敢開嗎?你...

    Kaede 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<