DOM常見的操作有哪些

一触幼、DOM

文檔對(duì)象模型 (DOM) 是 HTMLXML 文檔的編程接口

它提供了對(duì)文檔的結(jié)構(gòu)化的表述硼瓣,并定義了一種方式可以使從程序中對(duì)該結(jié)構(gòu)進(jìn)行訪問,從而改變文檔的結(jié)構(gòu)置谦,樣式和內(nèi)容

任何 HTMLXML文檔都可以用 DOM表示為一個(gè)由節(jié)點(diǎn)構(gòu)成的層級(jí)結(jié)構(gòu)

節(jié)點(diǎn)分很多類型堂鲤,每種類型對(duì)應(yīng)著文檔中不同的信息和(或)標(biāo)記,也都有自己不同的特性媒峡、數(shù)據(jù)和方法瘟栖,而且與其他類型有某種關(guān)系,如下所示:

<html>
    <head>
        <title>Page</title>
    </head>
    <body>
        <p>Hello World!</p >
    </body>
</html>

DOM像原子包含著亞原子微粒那樣谅阿,也有很多類型的DOM節(jié)點(diǎn)包含著其他類型的節(jié)點(diǎn)半哟。接下來我們先看看其中的三種:

<div>
    <p title="title">
        content
    </p >
</div>

上述結(jié)構(gòu)中,div签餐、p就是元素節(jié)點(diǎn)寓涨,content就是文本節(jié)點(diǎn),title就是屬性節(jié)點(diǎn)

二贱田、操作

日常前端開發(fā)缅茉,我們都離不開DOM操作

在以前,我們使用Jquery男摧,zepto等庫來操作DOM蔬墩,之后在vueAngular耗拓,React等框架出現(xiàn)后拇颅,我們通過操作數(shù)據(jù)來控制DOM(絕大多數(shù)時(shí)候),越來越少的去直接操作DOM

但這并不代表原生操作不重要乔询。相反樟插,DOM操作才能有助于我們理解框架深層的內(nèi)容

下面就來分析DOM常見的操作,主要分為:

  • 創(chuàng)建節(jié)點(diǎn)
  • 查詢節(jié)點(diǎn)
  • 更新節(jié)點(diǎn)
  • 添加節(jié)點(diǎn)
  • 刪除節(jié)點(diǎn)

創(chuàng)建節(jié)點(diǎn)

createElement

創(chuàng)建新元素竿刁,接受一個(gè)參數(shù)黄锤,即要?jiǎng)?chuàng)建元素的標(biāo)簽名

const divEl = document.createElement("div");

createTextNode

創(chuàng)建一個(gè)文本節(jié)點(diǎn)

const textEl = document.createTextNode("content");

createDocumentFragment

用來創(chuàng)建一個(gè)文檔碎片,它表示一種輕量級(jí)的文檔食拜,主要是用來存儲(chǔ)臨時(shí)節(jié)點(diǎn)鸵熟,然后把文檔碎片的內(nèi)容一次性添加到DOM

const fragment = document.createDocumentFragment();

當(dāng)請(qǐng)求把一個(gè)DocumentFragment 節(jié)點(diǎn)插入文檔樹時(shí),插入的不是 DocumentFragment自身负甸,而是它的所有子孫節(jié)點(diǎn)

createAttribute

創(chuàng)建屬性節(jié)點(diǎn)流强,可以是自定義屬性

const dataAttribute = document.createAttribute('custom');
consle.log(dataAttribute);

獲取節(jié)點(diǎn)

querySelector

傳入任何有效的css 選擇器痹届,即可選中單個(gè) DOM元素(首個(gè)):

document.querySelector('.element')
document.querySelector('#element')
document.querySelector('div')
document.querySelector('[name="username"]')
document.querySelector('div + p > span')

如果頁面上沒有指定的元素時(shí),返回 null

querySelectorAll

返回一個(gè)包含節(jié)點(diǎn)子樹內(nèi)所有與之相匹配的Element節(jié)點(diǎn)列表打月,如果沒有相匹配的队腐,則返回一個(gè)空節(jié)點(diǎn)列表

const notLive = document.querySelectorAll("p");

需要注意的是,該方法返回的是一個(gè) NodeList的靜態(tài)實(shí)例奏篙,它是一個(gè)靜態(tài)的“快照”柴淘,而非“實(shí)時(shí)”的查詢

關(guān)于獲取DOM元素的方法還有如下,就不一一述說

document.getElementById('id屬性值');返回?fù)碛兄付╥d的對(duì)象的引用
document.getElementsByClassName('class屬性值');返回?fù)碛兄付╟lass的對(duì)象集合
document.getElementsByTagName('標(biāo)簽名');返回?fù)碛兄付?biāo)簽名的對(duì)象集合
document.getElementsByName('name屬性值'); 返回?fù)碛兄付Q的對(duì)象結(jié)合
document/element.querySelector('CSS選擇器');  僅返回第一個(gè)匹配的元素
document/element.querySelectorAll('CSS選擇器');   返回所有匹配的元素
document.documentElement;  獲取頁面中的HTML標(biāo)簽
document.body; 獲取頁面中的BODY標(biāo)簽
document.all[''];  獲取頁面中的所有元素節(jié)點(diǎn)的對(duì)象集合型

除此之外报破,每個(gè)DOM元素還有parentNode悠就、childNodes千绪、firstChild充易、lastChildnextSibling荸型、previousSibling屬性盹靴,關(guān)系圖如下圖所示

1.png

更新節(jié)點(diǎn)

innerHTML

不但可以修改一個(gè)DOM節(jié)點(diǎn)的文本內(nèi)容,還可以直接通過HTML片段修改DOM節(jié)點(diǎn)內(nèi)部的子樹

// 獲取<p id="p">...</p >
var p = document.getElementById('p');
// 設(shè)置文本為abc:
p.innerHTML = 'ABC'; // <p id="p">ABC</p >
// 設(shè)置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p >的內(nèi)部結(jié)構(gòu)已修改

innerText瑞妇、textContent

自動(dòng)對(duì)字符串進(jìn)行HTML編碼稿静,保證無法設(shè)置任何HTML標(biāo)簽

// 獲取<p id="p-id">...</p >
var p = document.getElementById('p-id');
// 設(shè)置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自動(dòng)編碼,無法設(shè)置一個(gè)<script>節(jié)點(diǎn):
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p >

兩者的區(qū)別在于讀取屬性時(shí)辕狰,innerText不返回隱藏元素的文本改备,而textContent返回所有文本

style

DOM節(jié)點(diǎn)的style屬性對(duì)應(yīng)所有的CSS,可以直接獲取或設(shè)置蔓倍。遇到-需要轉(zhuǎn)化為駝峰命名

// 獲取<p id="p-id">...</p >
const p = document.getElementById('p-id');
// 設(shè)置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px'; // 駝峰命名
p.style.paddingTop = '2em';

添加節(jié)點(diǎn)

innerHTML

如果這個(gè)DOM節(jié)點(diǎn)是空的悬钳,例如,<div></div>偶翅,那么默勾,直接使用innerHTML = '<span>child</span>'就可以修改DOM節(jié)點(diǎn)的內(nèi)容,相當(dāng)于添加了新的DOM節(jié)點(diǎn)

如果這個(gè)DOM節(jié)點(diǎn)不是空的聚谁,那就不能這么做母剥,因?yàn)?code>innerHTML會(huì)直接替換掉原來的所有子節(jié)點(diǎn)

appendChild

把一個(gè)子節(jié)點(diǎn)添加到父節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)

舉個(gè)例子

<!-- HTML結(jié)構(gòu) -->
<p id="js">JavaScript</p >
<div id="list">
    <p id="java">Java</p >
    <p id="python">Python</p >
    <p id="scheme">Scheme</p >
</div>

添加一個(gè)p元素

const js = document.getElementById('js')
js.innerHTML = "JavaScript"
const list = document.getElementById('list');
list.appendChild(js);

現(xiàn)在HTML結(jié)構(gòu)變成了下面

<!-- HTML結(jié)構(gòu) -->
<div id="list">
    <p id="java">Java</p >
    <p id="python">Python</p >
    <p id="scheme">Scheme</p >
    <p id="js">JavaScript</p >  <!-- 添加元素 -->
</div>

上述代碼中,我們是獲取DOM元素后再進(jìn)行添加操作形导,這個(gè)js節(jié)點(diǎn)是已經(jīng)存在當(dāng)前文檔樹中环疼,因此這個(gè)節(jié)點(diǎn)首先會(huì)從原先的位置刪除,再插入到新的位置

如果動(dòng)態(tài)添加新的節(jié)點(diǎn)朵耕,則先創(chuàng)建一個(gè)新的節(jié)點(diǎn)炫隶,然后插入到指定的位置

const list = document.getElementById('list'),
const haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);

insertBefore

把子節(jié)點(diǎn)插入到指定的位置,使用方法如下:

parentElement.insertBefore(newElement, referenceElement)

子節(jié)點(diǎn)會(huì)插入到referenceElement之前

setAttribute

在指定元素中添加一個(gè)屬性節(jié)點(diǎn)憔披,如果元素中已有該屬性改變屬性值

const div = document.getElementById('id')
div.setAttribute('class', 'white');//第一個(gè)參數(shù)屬性名等限,第二個(gè)參數(shù)屬性值爸吮。

刪除節(jié)點(diǎn)

刪除一個(gè)節(jié)點(diǎn),首先要獲得該節(jié)點(diǎn)本身以及它的父節(jié)點(diǎn)望门,然后形娇,調(diào)用父節(jié)點(diǎn)的removeChild把自己刪掉

// 拿到待刪除節(jié)點(diǎn):
const self = document.getElementById('to-be-removed');
// 拿到父節(jié)點(diǎn):
const parent = self.parentElement;
// 刪除:
const removed = parent.removeChild(self);
removed === self; // true

刪除后的節(jié)點(diǎn)雖然不在文檔樹中了,但其實(shí)它還在內(nèi)存中筹误,可以隨時(shí)再次被添加到別的位置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桐早,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子厨剪,更是在濱河造成了極大的恐慌哄酝,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祷膳,死亡現(xiàn)場(chǎng)離奇詭異陶衅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)直晨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門搀军,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勇皇,你說我怎么就攤上這事罩句。” “怎么了敛摘?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵门烂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我兄淫,道長(zhǎng)屯远,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任拖叙,我火速辦了婚禮氓润,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘薯鳍。我一直安慰自己咖气,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布挖滤。 她就那樣靜靜地躺著崩溪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斩松。 梳的紋絲不亂的頭發(fā)上伶唯,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音惧盹,去河邊找鬼乳幸。 笑死瞪讼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粹断。 我是一名探鬼主播符欠,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼瓶埋!你這毒婦竟也來了希柿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤养筒,失蹤者是張志新(化名)和其女友劉穎曾撤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晕粪,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挤悉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兵多。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尖啡。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剩膘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盆顾,我是刑警寧澤怠褐,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站您宪,受9級(jí)特大地震影響奈懒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宪巨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一磷杏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捏卓,春花似錦极祸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒜田,卻和暖如春稿械,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冲粤。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工美莫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留页眯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓厢呵,卻偏偏與公主長(zhǎng)得像餐茵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子述吸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容