摘要:很多開發(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) /* *創(chuàng)建元素列表Hello world!
* * */
如果我們有一些數(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
摘要:一個軟件測試在職老人幫你詳細(xì)分析一下。在軟件測試行業(yè),前兩點(diǎn)可以結(jié)合起來說,就是大環(huán)境和前景以及人才缺口的問題。軟件測試屬于互聯(lián)網(wǎng)技術(shù)的一個分支,就是經(jīng)常被提到的行業(yè)。你零基礎(chǔ)轉(zhuǎn)行嗷,良心奉勸你不要自學(xué)。 一個軟件測試在職老人幫你詳細(xì)分析一下。先不說軟件測試領(lǐng)域,你想轉(zhuǎn)行的話,得知道這個行...
摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...
摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...
摘要:我發(fā)現(xiàn)使用這些命名空間會使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。 無論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個中熟手(作為web術(shù)語來說),你可能已經(jīng)意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視僭O(shè)你對這種CSS的方法有一個基礎(chǔ)的理解。 本文旨在對那...
摘要:列入全國計算機(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)氣、壓縮、做功和排氣過程,但你就是不去練如何開車,怎么上路。你確定,你敢開嗎?你...
閱讀 2087·2021-11-16 11:45
閱讀 583·2021-11-04 16:12
閱讀 1390·2021-10-08 10:22
閱讀 864·2021-09-23 11:52
閱讀 4150·2021-09-22 15:47
閱讀 3527·2021-09-22 15:07
閱讀 498·2021-09-03 10:28
閱讀 1743·2021-09-02 15:21