《DOM知識點總結(jié)》

DOM(文檔對象模型)是針對HTML和XML文檔的一個API,描繪了一個層次化的節(jié)點樹,允許我們添加绢馍、移除和修改頁面的某一部分羹膳。目前流行的各種前端框架睡互,對于頁面結(jié)構(gòu)的調(diào)整更新構(gòu)建都是基于DOM的原生API來實現(xiàn)的,而我們平時在進(jìn)行前端開發(fā)時也或多或少會用到DOM原生操作陵像,尤其是“拋棄”jQuery這個框架之后就珠,原生的DOM操作越來越重要,今天就來總結(jié)一些常見的DOM屬性和操作方法醒颖。

Node類型

DOM將文檔描繪成了一個多層次節(jié)點構(gòu)成的結(jié)構(gòu)妻怎,節(jié)點有很多的類型,每個類型又有不同的特點泞歉、數(shù)據(jù)和方法逼侦,節(jié)點之間也存在著相互的關(guān)系匿辩,同級關(guān)系,子父級關(guān)系等等榛丢。整個文檔就是由一個個節(jié)點構(gòu)建起來的樹铲球,就是我們經(jīng)常說的DOM樹。
每個節(jié)點(node)都有一個nodeType屬性涕滋,表明節(jié)點的類型睬辐,下面先簡單列舉一下常見的節(jié)點類型:

  • Node.ELEMENT_NODE(1)-----------元素節(jié)點,nodeType值為1
  • Node.ATTRIBUTE_NODE(2)---------屬性節(jié)點宾肺,nodeType值為2
  • Node.TEXT_NODE(3)--------------文本節(jié)點溯饵,nodeType值為3
  • Node.COMMENT_NODE(8)-----------注釋節(jié)點,nodeType值為8
  • Node.DOCUMENT_NODE(9)----------文檔節(jié)點锨用,nodeType值為9
  • Node.DOCUMENT_TYPE_NODE(10)----doctype節(jié)點丰刊,nodeType值為10

可以通過節(jié)點的nodeType值來判斷節(jié)點類型

if(someNode.nodeType == 1){
  console.log("Node is an element.")
}

節(jié)點關(guān)系

節(jié)點之間存在著這樣或那樣的關(guān)系,每個node都有一個childNodes屬性增拥,其中保存著一個NodeList對象啄巧,有length屬性,但不是一個Array實例掌栅,可以像下面一樣訪問里面存著的node:

var fistChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

還有一些屬性:

  • someNode.nextSibling 同級下一個節(jié)點
  • someNode.previousSibling 同級前一個節(jié)點
  • someNode.firstChild 節(jié)點的第一個子節(jié)點
  • someNode.lastChild 節(jié)點的最后一個子節(jié)點
  • someNode.parentNode 節(jié)點的父節(jié)點

節(jié)點操作方法

常見的操作方法

  • someNode.appendChild(newNode)--------------在節(jié)點的childNodes末尾添加一個新節(jié)點秩仆,返回new
  • someNode.insertBefore(newNode, whoNode)----在who前面添加一個new節(jié)點,返回new
  • someNode.replaceChild(newNode, whoNode)----將who替換為new節(jié)點猾封,返回who
  • someNode.removeChild(whoNode)--------------將who移除澄耍,返回who

以上方法都是在父節(jié)點上的操作,沒有子節(jié)點節(jié)點調(diào)用這些方法會報錯晌缘。

兩個特例方法

這倆方法有沒有子節(jié)點都可以使用:

cloneNode()

這個方法用來復(fù)制調(diào)用它的節(jié)點齐莲,可以傳一個參數(shù)true來進(jìn)行深復(fù)制;

//淺復(fù)制磷箕,只復(fù)制節(jié)點本身选酗,不會復(fù)制節(jié)點內(nèi)部
var copyNode = someNode.cloneNode(false);

//深復(fù)制,復(fù)制節(jié)點內(nèi)部子節(jié)點
var deepCopy = someNode.cloneNode(true);

要注意的一點是岳枷,cloneNode的默認(rèn)參數(shù)在不同的規(guī)范下芒填,取true和false都有可能,建議強制寫明參數(shù)空繁,不使用默認(rèn)值(其實也不知道默認(rèn)值到底是啥)氢烘。

normalize()

這個方法是文本節(jié)點(Text_Node)的專用方法,在someNode上調(diào)用時家厌,如果在其后代節(jié)點找到了空文本節(jié)點播玖,就刪除這個空文本節(jié)點;如果找到了相鄰的文本節(jié)點(一般來說直接寫的html都只有一個文本節(jié)點饭于,除非我們用createTextNode()這種方法創(chuàng)建文本節(jié)點蜀踏,才有可能出現(xiàn)相鄰的文本節(jié)點)维蒙,則合并為一個節(jié)點。

元素節(jié)點ELement_Node

其實元素節(jié)點簡單來說就是html中的標(biāo)簽果覆,什么p標(biāo)簽颅痊,h1標(biāo)簽等等,先說一下它的特性:

  • nodeType值為1局待;
  • nodeName值為元素標(biāo)簽名斑响;也可以使用tagName獲取,注意大小寫問題
  • nodeValue值為null钳榨;它也沒啥值好用的
  • parentNode可能為DocumentElement舰罚;文檔的子節(jié)點或者其他element的子節(jié)點
  • 子節(jié)點可能是:ElementText薛耻、Comment等等营罢;

HTML元素

所有的HTML元素都是由HTMLElement類型表示,它就是繼承自Element饼齿,然后添加了一些屬性饲漾,其實感覺跟ELement一個東西,主要有以下屬性:

  • id;------------就是div的id么缕溉,標(biāo)識符一個
  • title;---------就是那個title
  • lang和dir;-----很少用
  • className;-----class的名字結(jié)合

其中className屬性考传,這個注意一下,返回的是一個class名稱的字符串合集证鸥,比如"item active test"伙菊,需要自己用字符串方法拆分操作它,后來HTML5就新增了一個classList屬性敌土,返回的是個class數(shù)組,比['item', 'active', 'test']运翼,可以用數(shù)組的方式操作class名稱返干,就很方便了。

classList屬性有自己的幾個操作方法:

  • add(value);----------將給定的字符串添加到列表血淌,如果有矩欠,則不添加
  • contains(value);-----列表里面有沒有給定的值,返回true/false
  • remove(value);-------刪除列表中給定的值
  • toggle(value);-------沒有就添加悠夯,有就刪除
div.classList.remove('item');
div.classList.add('current');
div.classList.toggle('active');

操作特性

操作div元素的屬性癌淮,就是常見的幾種方法,列舉一下:

  • getAttribute();
  • setAttribute();
  • removeAttribute();

我們還經(jīng)常自定義屬性沦补,比如在標(biāo)簽里定義個id='1'乳蓄,HTML5規(guī)范建議自定義屬性加上data-前綴,表明是自定的屬性夕膀,這樣可以使用div.dataset.id取得屬性值虚倒。
還有一個Attributes屬性美侦,不展開說了,不怎么用到魂奥。

創(chuàng)建元素節(jié)點

可以使用document.createElement()方法創(chuàng)建元素節(jié)點菠剩。再配合node的操作方法,進(jìn)行各種穿插耻煤。

屬性節(jié)點Attribute_Node

屬性節(jié)點不被認(rèn)為是DOM文檔樹的一部分具壮,簡單說一下它的特性:

  • nodeType值為2;
  • nodeName值為特性的名稱哈蝇;
  • nodeValue值為特性的值棺妓;
  • parentNode為null
  • 沒有子節(jié)點

操作屬性一般用上面的getAttribute()setAttribute()买鸽、removeAttribute()涧郊。

文本節(jié)點Text_Node

文本節(jié)點簡單說就是標(biāo)簽里的內(nèi)容,比如<div>hello world</div>中的'hello world'眼五,先說一下它的特性:

  • nodeType值為3妆艘;
  • nodeName值為#text;
  • nodeValue值為節(jié)點包含的文本;
  • parentNode可能Element看幼;
  • 沒有子節(jié)點批旺;

開始和結(jié)束標(biāo)簽之間只要有內(nèi)容,就會創(chuàng)建一個文本節(jié)點:

//沒有文本節(jié)點
<div></div>

//有空格诵姜,故有一個文本節(jié)點
<div> </div>

//有內(nèi)容汽煮,故有一個文本節(jié)點
<div>hello world</div>
var textNode = div.firstChild;
textNode.nodeValue;  // hello world

創(chuàng)建文本節(jié)點

可以通過document.createTextNode('hello world')創(chuàng)建一個文本節(jié)點,再配合node的操作方法棚唆,進(jìn)行各種穿插暇赤。
一般來講,一個元素只有一個文本節(jié)點宵凌,但是你要是硬搞幾個相鄰節(jié)點鞋囊,也是可行的,然后就有了normalize()spliteText()這倆方法:

var element = document.createElement('div');
element.className = 'message';

var textNode = document.createTextNode('hello world');
element.appendChild(textNode);

var anotherTextNode = document.createTextNode('Yep!');
element.appendChild(anotherTextNode);   //這樣就有了倆文本節(jié)點

alert(element.childNodes.length);   // 2
element.normalize();
alert(element.childNodes.length);      // 1
alert(element.firstChild.nodeValue);   // 'hello worldYep!'

spliteText()是將文本節(jié)點進(jìn)行分割瞎惫,具體細(xì)節(jié)不想講了溜腐,碰見了再查。

文檔節(jié)點Document_Node

文檔節(jié)點表示整個HTML頁面瓜喇,document對象也是window對象的一個屬性挺益,說一下它的特性:

  • nodeType值為9;
  • nodeName值為#document;
  • nodeValue值為null乘寒;
  • parentNode值為null望众;
  • 子節(jié)點可能是一個DocumentTypeElementComment黍檩;

子節(jié)點

document的子節(jié)點也就是常見的html叉袍、headbody刽酱、doctype等喳逛,可以用下面的屬性取得它們的引用:

var html = document.documentElement;
var head = document.head;            // HTML5新定義的
var body = document.body;
var doctype = document.doctype;

文檔信息

僅做了解:

var originTitle = document.title;   // 取得頁面的title
document.title = 'New Title';       // 設(shè)置頁面title

var url = document.URL;             // 取得頁面的完整URL
var domin = document.domin;         // 取得域名
var referrer = document.referrer;   // 取得來源頁面的URL

查找元素

document.getElementById()

根據(jù)id獲取元素的引用,如果找不到棵里,就返回null润文,只能使用document調(diào)用。

getElementsByTagName()

根據(jù)標(biāo)簽名獲取一個HTMLCollection元素列表殿怜,跟NodeList對象類似典蝌。可以使用document或者element調(diào)用

var images = document.getElementsByTagName('img');   // document調(diào)用
images.length;    // 數(shù)量
images[0].src;
images.item(0).src;

var test = element.getElementsByTagName('a');    // element調(diào)用

還可以傳入一個*來獲取文檔中的所有元素头谜。

getElementsByClassName()

根據(jù)class類名查找骏掀,可以使用document或者element調(diào)用

var test = document.getElementsByClassName("item active");
var test1 = element.getElementsByClassName("item");

DOM的擴展

DOM還有一個SelectorsAPI的擴展,另一個是HTML5柱告,下面說一下SelectorsAPI截驮,都可以通過element或者document調(diào)用。

querySelector()

接受一個CSS選擇符际度,返回匹配到的第一個元素葵袭,沒有找到就返回null。

var body = document.querySelector('body');
var myDiv = document.querySelector('#myDiv');

querySelectorAll()

同樣接受一個CSS選擇符乖菱,返回一個NodeList實例坡锡。

var ems = document.getElementById('myDiv').querySelectorAll('em');
var strongs = document.querySelectorAll('p strong');
strongs.item(1);
strongs[2];

文檔寫入

  • wirte();
  • wirteIn();-----跟write()一樣,只不過會在寫入的字符串最后添加一個'/n'
  • close();
  • open();

HTML5新增了innerHTML()outerHTML()兩個方法窒所,不同的是outerHTML()會包含調(diào)用元素本身鹉勒。另外一個需要了解的方法是contains(),用來判斷某個節(jié)點是不是調(diào)用節(jié)點的子節(jié)點:

document.documentElement.contains(document.body);   // true

本次先總結(jié)這些吵取,下次我們來總結(jié)一下原生操作樣式div.style.color和關(guān)于offsetWidth禽额、scrollTop等的知識點。

歡迎沒事的時候來我的個人博客看一看

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末海渊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子哲鸳,更是在濱河造成了極大的恐慌臣疑,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徙菠,死亡現(xiàn)場離奇詭異讯沈,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進(jìn)店門缺狠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來问慎,“玉大人,你說我怎么就攤上這事挤茄∪绲穑” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵穷劈,是天一觀的道長笼恰。 經(jīng)常有香客問我,道長歇终,這世上最難降的妖魔是什么社证? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮评凝,結(jié)果婚禮上追葡,老公的妹妹穿的比我還像新娘。我一直安慰自己奕短,他們只是感情好宜肉,可當(dāng)我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著篡诽,像睡著了一般崖飘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杈女,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天朱浴,我揣著相機與錄音,去河邊找鬼达椰。 笑死翰蠢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的啰劲。 我是一名探鬼主播梁沧,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蝇裤!你這毒婦竟也來了廷支?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤栓辜,失蹤者是張志新(化名)和其女友劉穎恋拍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藕甩,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡施敢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僵娃。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡概作,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出默怨,到底是詐尸還是另有隱情讯榕,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響捣郊,放射性物質(zhì)發(fā)生泄漏压真。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦栽燕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朵夏,卻和暖如春蔼啦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仰猖。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工捏肢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饥侵。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓鸵赫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親躏升。 傳聞我的和親對象是個殘疾皇子辩棒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,442評論 2 359

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

  • ??DOM(文檔對象模型)是針對 HTML 和 XML 文檔的一個 API(應(yīng)用程序編程接口)一睁。 ??DOM 描繪...
    霜天曉閱讀 3,655評論 0 7
  • 本章內(nèi)容 理解包含不同層次節(jié)點的 DOM 使用不同的節(jié)點類型 克服瀏覽器兼容性問題及各種陷阱 DOM 是針對 HT...
    悶油瓶小張閱讀 642評論 0 1
  • 原文 鏈接 關(guān)注公眾號獲取更多資訊 一、基本類型介紹 1.1 Node類型 DOM1級定義了一個Node接口佃却,該接...
    程序員poetry閱讀 3,938評論 7 34
  • ??DOM 1 級主要定義的是 HTML 和 XML 文檔的底層結(jié)構(gòu)双霍。 ??DOM2 和 DOM3 級則在這個結(jié)構(gòu)...
    霜天曉閱讀 1,452評論 1 3
  • 如此文藝清新的小街~~~坐進(jìn)去懶懶地翻動桌邊的書籍,點上一杯香醇濃郁的摩卡丘逸!就可泡上一個下午单鹿! 之外,在武漢意外的...
    木子階閱讀 453評論 0 3