DOM的映射機(jī)制

前言

這在我們平常操作 DOM 的時(shí)候司空見慣。就比如:我通過獲取一個(gè)元素來改變其樣式,自然而然的反映到 HTML 頁面中。

但是,我們操作 JS 對(duì)象的時(shí)候,本質(zhì)上操作的是 JS 堆內(nèi)存,為什么會(huì)反映到頁面中呢?就是因?yàn)闉g覽器存在這個(gè) DOM 的映射機(jī)制。

1. 什么是 DOM 的映射機(jī)制?

我們使用 JS 從頁面獲取到的元素對(duì)象,或者自己手動(dòng)創(chuàng)建的已經(jīng)插入頁面的元素對(duì)象,與頁面中的 HTML 元素是綁定在一起的。也就是說修改其中一個(gè),另一個(gè)也會(huì)跟著自動(dòng)修改。這就是 DOM 的映射機(jī)制。

2. 形成映射的幾種情形

改變?cè)貙?duì)象的屬性

這是我們最常用到的一種情形。當(dāng)我們需要為元素添加自定義屬性、或者修改屬性等,就可以從頁面中獲取到元素對(duì)象,然后對(duì)其進(jìn)行修改,就能夠自動(dòng)反映到 HTML 頁面元素上。

//=> 修改從頁面中獲取的元素樣式
Div.style.color = 'red';

//=> 修改已經(jīng)插入頁面的元素的屬性
var p = document.createElement('p');
box.appendChild(p);
p.dataset.index = 1;

這兩種方式得到的元素對(duì)象,修改其屬性,都能夠直接反映到頁面中,不需要再次插入頁面中。

在元素內(nèi)部繼續(xù)添加元素

//=> 在其內(nèi)部插入標(biāo)簽或文本
var list = Div.getElementsByTagName('li');
console.log(list); // 空的元素集合
Div.innerHTML('<li></li>');
console.log(list); // 有一個(gè)元素集合

//=> 添加自己創(chuàng)建的元素對(duì)象,同樣原理
Div.appendChild(p);

在容器中的數(shù)據(jù)綁定前,我們獲取容器中元素,得到一個(gè)空的元素集合,容器數(shù)據(jù)綁定后,我們不需要重新獲取,DOM 的映射機(jī)制會(huì)幫我們把新增加的元素映射到之前獲取的空集合中,讓其變?yōu)橛性氐募稀?/p>

在頁面中追加已有元素

list = Div.getElementsByTagName('li')[0];
Div.appendChild(list);

appendChild 在追加元素對(duì)象的時(shí)候,如果這個(gè)元素在容器中已經(jīng)存在,此時(shí)并不是克隆一份新的追加到末尾,而是把原有的元素移動(dòng)到末尾。

其根本原因在于,同一個(gè)元素在頁面中,只能夠有一個(gè)位置。把 JS 元素對(duì)象插入頁面中某個(gè)位置,實(shí)際上就是把其綁定的 HTML 元素移動(dòng)到那個(gè)位置上。

這里的元素已經(jīng)存在有兩種情形:

  • 元素是從頁面中獲取到的
  • 創(chuàng)建的元素已經(jīng)添加過一次,再次添加時(shí)

因此,就無需手動(dòng)移除原先的元素,再進(jìn)行添加。直接插入即可。

3. 特殊情況

querySelectAll 獲取的集合是靜態(tài)集合(staticNodeList),不存在上述所謂的映射機(jī)制,基于這個(gè)方法,數(shù)據(jù)綁定完成后需要重新獲取一次才可以。

var box = document.querySelectorAll('#box');
var box1 = document.getElementById('box');
console.log(box); //=> 獲取到的是 NodeList 對(duì)象
console.dir(box1); //=> 而這里獲取到的是 HTMLElement 的實(shí)例

NodeList 不存在與 HTML 頁面元素的映射,而且沒有很多 HTMLElement 實(shí)例才擁有的方法。因此,千萬不要使用這個(gè)方法。

另外,jQuery 中獲取的元素同樣不存在這些映射,實(shí)現(xiàn)映射需要使用其內(nèi)部的方法,而且要使用原生 HTMLElement 實(shí)例的方法,需要通過后面加 [0] 的方法轉(zhuǎn)換為原生元素對(duì)象。

?著作權(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.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,242評(píng)論 8 265
  • 動(dòng)車上一覺醒來看見車窗上的映像,感覺自己甚是可愛,也甚感饑餓… 想起了臨出門時(shí)老爸塞在包里的蘋果,甜 脆 紅。...
    讓我說閱讀 223評(píng)論 0 0
  • 簡素gyl閱讀 197評(píng)論 0 0
  • 過了個(gè)年落了一堆任務(wù),比如最近沒有看書,比如簡書沒有持續(xù)更新,英語閱讀沒有落下的原因還是因?yàn)槔蠋熃o我們放了七天假,...
    楊姣娜閱讀 182評(píng)論 2 2
  • ① 平等溝通,不高高在上,例如:“我們一起看下這本書講的什么吧,你有什么想法都可以說出來。”“你這個(gè)想法很好,跟我...
    七零八零閱讀 313評(píng)論 0 1

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