[JavaScript] (Day-17) - DOM 基本操作

Happiness takes no account of time. 幸福不覺光陰過。

由于 HTML 文檔被瀏覽器解析后就是一棵 DOM 樹简肴,要改變 HTML 的結(jié)構(gòu)吐限,就需要通過 JavaScript 來操作 DOM稠项。

操作一個(gè) DOM 節(jié)點(diǎn)實(shí)際上就是這么幾個(gè)操作:

  • 更新:更新該 DOM 節(jié)點(diǎn)的內(nèi)容驾荣,相當(dāng)于更新了該 DOM 節(jié)點(diǎn)表示的HTML 的內(nèi)容;
  • 遍歷:遍歷該 DOM 節(jié)點(diǎn)下的子節(jié)點(diǎn)帆吻,以便進(jìn)行進(jìn)一步操作域那;
  • 添加:在該 DOM 節(jié)點(diǎn)下新增一個(gè)子節(jié)點(diǎn),相當(dāng)于動態(tài)增加了一個(gè) HTML 節(jié)點(diǎn)猜煮;
  • 刪除:將該節(jié)點(diǎn)從 HTML 中刪除次员,相當(dāng)于刪掉了該 DOM 節(jié)點(diǎn)的內(nèi)容以及它包含的所有子節(jié)點(diǎn)。

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

在操作一個(gè) DOM 節(jié)點(diǎn)前王带,我們需要通過各種方式先拿到這個(gè) DOM 節(jié)點(diǎn)淑蔚。

最常用的方法是:

  • document.getElementById()
  • document.getElementsByTagName()
  • 以及 CSS 選擇器 document.getElementsByClassName()

由于ID在 HTML 文檔中是唯一的,所以document.getElementById()可以直接定位唯一的一個(gè)DOM節(jié)點(diǎn);

document.getElementsByTagName()document.getElementsByClassName()總是返回一組 DOM 節(jié)點(diǎn)愕撰。要精確地選擇 DOM刹衫,可以先定位父節(jié)點(diǎn),再從父節(jié)點(diǎn)開始選擇搞挣,以縮小范圍带迟。

// 返回ID為'test'的節(jié)點(diǎn):
var test = document.getElementById('test');

// 先定位ID為'test-table'的節(jié)點(diǎn),再返回其內(nèi)部所有tr節(jié)點(diǎn):
var trs = document.getElementById('test-table').getElementsByTagName('tr');

// 先定位ID為'test-div'的節(jié)點(diǎn)囱桨,再返回其內(nèi)部所有class包含red的節(jié)點(diǎn):
var reds = document.getElementById('test-div').getElementsByClassName('red');

// 獲取節(jié)點(diǎn)test下的所有直屬子節(jié)點(diǎn):
var cs = test.children;

// 獲取節(jié)點(diǎn)test下第一個(gè)仓犬、最后一個(gè)子節(jié)點(diǎn):
var first = test.firstElementChild;
var last = test.lastElementChild;

第二種方法是使用querySelector()querySelectorAll(),需要了解selector語法舍肠,然后使用條件來獲取節(jié)點(diǎn)搀继,更加方便:

// 通過 querySelector 獲取 ID 為 q1 的節(jié)點(diǎn):
var q1 = document.querySelector('#q1');

// 通過 querySelectorAll 獲取 q1 節(jié)點(diǎn)內(nèi)的符合條件的所有節(jié)點(diǎn):
var ps = q1.querySelectorAll('div.highlighted > p');

更新 DOM

拿到一個(gè) DOM 節(jié)點(diǎn)后,我們可以對它進(jìn)行更新,直接修改節(jié)點(diǎn)的文本

方式一:修改innerHTML屬性翠语,這個(gè)方式非常強(qiáng)大叽躯,不但可以修改一個(gè)DOM節(jié)點(diǎn)的文本內(nèi)容,還可以直接通過HTML片段修改DOM節(jié)點(diǎn)內(nèi)部的子樹

// 獲取<p id="p_id">...</p>
var p = document.getElementById('p_id');

// 設(shè)置文本為ABC:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>

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

方式二: 修改innerTexttextContent屬性肌括,這樣可以自動對字符串進(jìn)行 HTML 編碼险毁,保證無法設(shè)置任何HTML標(biāo)簽

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

// 獲取<p id="p_id">...</p>
var p = document.getElementById('p_id');

// 設(shè)置文本:
p.innerText = '<script>alert("Hi")</script>';

// HTML被自動編碼畔况,無法設(shè)置一個(gè)<script>節(jié)點(diǎn):
// <p id="p-id"><script>alert("Hi")</script></p>

插入 DOM

獲得某個(gè) DOM 節(jié)點(diǎn),然后在這個(gè) DOM 節(jié)點(diǎn)內(nèi)插入新的 DOM

方式一:使用appendChild慧库,把一個(gè)子節(jié)點(diǎn)添加到父節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)

例如:

<!-- 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>

idjs 的標(biāo)簽插入到 <div>...</div> 便簽最后一項(xiàng)

var js = document.getElementById('js');
var list = document.getElementById('list');
list.appendChild(js);

結(jié)果:

<!-- 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>

上面是把已知的元素插入到指定位置跷跪,但更多的時(shí)候我們會從零創(chuàng)建一個(gè)新的節(jié)點(diǎn),然后插入到指定位置:

var list = document.getElementById('list');
var swift = document.createElement('p');
swift.id = 'swift';
swift.innerText = 'Swift';
list.appendChild(swift);

結(jié)果:

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


方式二: 使用 insertBefore 把子節(jié)點(diǎn)插入到指定的位置

使用parentElement.insertBefore(newElement, referenceElement);齐板,子節(jié)點(diǎn)會插入到referenceElement之前吵瞻。

還是以上面的 HTML 為例,假定我們要把Swift插入到Python之前:

<!-- HTML結(jié)構(gòu) -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>
var list = document.getElementById('list');
var ref = document.getElementById('python');
var swift = document.createElement('p');
swift.id = 'swift';
swift.innerText = 'Swift';
list.insertBefore(swift, ref);
<!-- HTML結(jié)構(gòu) -->
<div id="list">
    <p id="java">Java</p>
    <p id="swift">Swift</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>


刪除DOM

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

// 拿到待刪除節(jié)點(diǎn):
var self = document.getElementById('to-be-removed');

// 拿到父節(jié)點(diǎn):
var parent = self.parentElement;

// 刪除:
var removed = parent.removeChild(self);
removed === self; // true

注意济舆,當(dāng)從子節(jié)點(diǎn)數(shù)組中刪除節(jié)點(diǎn)時(shí)卿泽,需要防止數(shù)組越界

<div id="parent">
    <p>First</p>
    <p>Second</p>
</div>

執(zhí)行刪除操作

var parent = document.getElementById('parent');

parent.removeChild(parent.children[0]);

parent.removeChild(parent.children[1]); // <-- 瀏覽器報(bào)錯(cuò)

報(bào)錯(cuò)原因:

當(dāng)<p>First</p>節(jié)點(diǎn)被刪除后,parent.children的節(jié)點(diǎn)數(shù)量已經(jīng)從2變?yōu)榱?code>1滋觉,索引[1]已經(jīng)不存在了签夭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市椎侠,隨后出現(xiàn)的幾起案子第租,更是在濱河造成了極大的恐慌,老刑警劉巖我纪,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慎宾,死亡現(xiàn)場離奇詭異,居然都是意外死亡浅悉,警方通過查閱死者的電腦和手機(jī)趟据,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仇冯,“玉大人之宿,你說我怎么就攤上這事】良幔” “怎么了比被?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泼舱。 經(jīng)常有香客問我等缀,道長,這世上最難降的妖魔是什么娇昙? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任尺迂,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘噪裕。我一直安慰自己蹲盘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布膳音。 她就那樣靜靜地躺著召衔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祭陷。 梳的紋絲不亂的頭發(fā)上苍凛,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機(jī)與錄音兵志,去河邊找鬼醇蝴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛想罕,可吹牛的內(nèi)容都是我干的悠栓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼弧呐,長吁一口氣:“原來是場噩夢啊……” “哼闸迷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起俘枫,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤腥沽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后鸠蚪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體今阳,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年茅信,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盾舌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蘸鲸,死狀恐怖妖谴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酌摇,我是刑警寧澤膝舅,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站窑多,受9級特大地震影響仍稀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜埂息,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一技潘、第九天 我趴在偏房一處隱蔽的房頂上張望遥巴。 院中可真熱鬧,春花似錦享幽、人聲如沸铲掐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迹炼。三九已至,卻和暖如春颠毙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背砂碉。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工蛀蜜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人增蹭。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓滴某,卻偏偏與公主長得像,于是被迫代替她去往敵國和親滋迈。 傳聞我的和親對象是個(gè)殘疾皇子霎奢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

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