DOM 之通俗易懂讲解
? DOM是所有前端開(kāi)發(fā)每天打交道的東西,但是隨著jQuery等庫(kù)的出現(xiàn),大大簡(jiǎn)化了DOM操作,導(dǎo)致大家慢慢的“遺忘”了它的本來(lái)面貌。不過(guò),要想深入學(xué)習(xí)前端知識(shí),對(duì)DOM的了解是不可或缺的,所以本文力圖系統(tǒng)的講解下DOM的相關(guān)知識(shí),如有遺漏或錯(cuò)誤,還請(qǐng)大家指出一起討論^ ^。
一、DOM是什么?
DOM(文檔對(duì)象模型)是針對(duì)HTML和XML文檔的一個(gè)API,通過(guò)DOM可以去改變文檔。
這個(gè)說(shuō)法很官方,大家肯定還是不明白。
舉個(gè)例子:我們有一段HTML,那么如何訪問(wèn)第二層第一個(gè)節(jié)點(diǎn)呢,如何把最后一個(gè)節(jié)點(diǎn)移動(dòng)到第一個(gè)節(jié)點(diǎn)上面去呢?
DOM就是定義了如果做類似操作,那么應(yīng)該怎么做的標(biāo)準(zhǔn)。比如用getElementById來(lái)訪問(wèn)節(jié)點(diǎn),用insertBefore來(lái)插入節(jié)點(diǎn)。
當(dāng)瀏覽器載入HTML時(shí),會(huì)生成相應(yīng)的DOM樹(shù)。
簡(jiǎn)而言之,DOM可以理解為一個(gè)訪問(wèn)或操作HTML各種標(biāo)簽的實(shí)現(xiàn)標(biāo)準(zhǔn)。
對(duì)于一個(gè)HTML來(lái)說(shuō),文檔節(jié)點(diǎn)Document(看不到的)是它的根節(jié)點(diǎn),對(duì)應(yīng)的對(duì)象便是document對(duì)象(嚴(yán)格講是子類HTMLDocument對(duì)象,下面單獨(dú)介紹Document類型時(shí)會(huì)指出)。
換句話說(shuō)存在一個(gè)文檔節(jié)點(diǎn)Document,然后它有子節(jié)點(diǎn),比如通過(guò)document.getElementsByTagName("html"),得到類型為元素節(jié)點(diǎn)的Element html。
每一段HTML標(biāo)記都可以用相應(yīng)的節(jié)點(diǎn)表示,例如:
HTML元素通過(guò)元素節(jié)點(diǎn)表示,注釋通過(guò)注釋節(jié)點(diǎn)表示,文檔類型通過(guò)文檔類型節(jié)點(diǎn)表示等。
一共定義了12種節(jié)點(diǎn)類型,而這些類型又都繼承自Node類型。
所以我們首先講Node類型,因?yàn)檫@個(gè)類型的方法是所有節(jié)點(diǎn)都會(huì)繼承的。
二、Node類型(基類,所有節(jié)點(diǎn)都繼承了它的方法)
Node是所有節(jié)點(diǎn)的基類型,所有節(jié)點(diǎn)都繼承自它,所以所有節(jié)點(diǎn)都有一些共同的方法和屬性。
先講Node類型的屬性
首先是nodeType屬性,用來(lái)表明節(jié)點(diǎn)類型的,例如:
document.nodeType; // 返回 9 ,其中document對(duì)象為文檔節(jié)點(diǎn)Document的實(shí)例這里面,9代表的就是DOCUMENT_NODE節(jié)點(diǎn)的意思,可以通過(guò)Node.DOCUMENT_NODE查看節(jié)點(diǎn)對(duì)應(yīng)的數(shù)字
document.nodeType === Node.DOCUMENT_NODE; // true至于一共有哪些節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的數(shù)字又是多少,這個(gè)可以問(wèn)谷歌就知道了。反正常用的就是元素節(jié)點(diǎn)Element(對(duì)應(yīng)數(shù)字為1)和文本節(jié)點(diǎn)Text(對(duì)應(yīng)數(shù)字為3)?
然后常用的還有nodeName和nodeValue
對(duì)于元素節(jié)點(diǎn) nodeName就是標(biāo)簽名,nodeValue就是null
對(duì)于文本節(jié)點(diǎn) nodeName為"#text"(chrome里面測(cè)試的),nodeValue就是實(shí)際的值
每個(gè)節(jié)點(diǎn)還有childNodes屬性,這是個(gè)十分重要的屬性,它保存了這個(gè)節(jié)點(diǎn)所有直接子元素
調(diào)用childNodes返回的是一個(gè)NodeList對(duì)象,它極其像數(shù)組,但是有一個(gè)最關(guān)鍵的地方,它是動(dòng)態(tài)查詢的,也就是說(shuō)每次調(diào)用它都會(huì)對(duì)DOM結(jié)構(gòu)查詢,所以對(duì)它的使用需要慎重,注意性能。
訪問(wèn)childNodes可以使用數(shù)組下表或者item方法
然后各個(gè)節(jié)點(diǎn)還存在各種屬性讓它們可以相互訪問(wèn),下圖很好的總結(jié)了
比較有用的方法和屬性:
1、hasChildNodes()
如果包含子節(jié)點(diǎn)就返回true,比查詢childNodes的length來(lái)的簡(jiǎn)單。
2、ownerDocument
返回文檔節(jié)點(diǎn)的引用(在html里面也就是document對(duì)象)
再介紹下Node類型常用的方法
appendChild()方法可以在節(jié)點(diǎn)的childNodes的末尾增加一個(gè)節(jié)點(diǎn),值得注意的是如果這個(gè)節(jié)點(diǎn)是已經(jīng)存在在文檔中的,那么便會(huì)刪除原節(jié)點(diǎn),感覺(jué)上就像是移動(dòng)節(jié)點(diǎn)一樣。
insertBefore()方法接受兩個(gè)參數(shù),一個(gè)是插入的節(jié)點(diǎn),另外一個(gè)是參照的節(jié)點(diǎn)。如果第二個(gè)參數(shù)為null,則insertBefore和appendChild效果一樣。否則便會(huì)把節(jié)點(diǎn)插入到參照節(jié)點(diǎn)之前。這里要注意的是,如果第二個(gè)參數(shù)不為null,那么插入的節(jié)點(diǎn)不能是已經(jīng)存在的節(jié)點(diǎn)。
replaceChild()方法可以替換節(jié)點(diǎn),接受兩個(gè)參數(shù),需要插入的節(jié)點(diǎn)和需要替換的節(jié)點(diǎn)。返回被替換掉的節(jié)點(diǎn)。
removeChild()移除節(jié)點(diǎn)。這里有個(gè)常見(jiàn)需求,比如我有一個(gè)節(jié)點(diǎn) #waste-node ,那么如何移除它呢?
var wasteNode = document.getElementById("waste-node"); wasteNode.parentNode.removeClhid(wasteNode); // 先拿到父節(jié)點(diǎn),再調(diào)用removeClild刪除自己這里先暫停一下,不知道大家注意到?jīng)]有,以上的幾個(gè)方法都是操作某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn),也就是說(shuō),操作前必須找到父節(jié)點(diǎn)(通過(guò)parentNode來(lái)找)
接下來(lái)說(shuō)下復(fù)制節(jié)點(diǎn)的方法:
cloneNode();復(fù)制節(jié)點(diǎn),接受一個(gè)參數(shù) true或者false。如果true就是復(fù)制那個(gè)節(jié)點(diǎn)和它的子節(jié)點(diǎn)。如果是false,就是復(fù)制節(jié)點(diǎn)本身(復(fù)制出來(lái)的節(jié)點(diǎn)就會(huì)沒(méi)有任何子元素)。這個(gè)方法返回復(fù)制的節(jié)點(diǎn),如果需要操作它,那么需要借助前面講的4個(gè)方法來(lái)把這個(gè)節(jié)點(diǎn)放入到html中去。
至此,Node類型的常見(jiàn)屬性和方法都介紹完了。結(jié)合開(kāi)頭講的,所有節(jié)點(diǎn)類型都繼承自Node類型,所以這些方法是所有節(jié)點(diǎn)都有的。
三、Document類型
最開(kāi)始講DOM是什么的時(shí)候提到了Document類型。其實(shí)關(guān)于這個(gè)類型最重要的是它的一個(gè)子類HTMLDocument有一個(gè)實(shí)例對(duì)象document。而這個(gè)document對(duì)象是我們最常用的一個(gè)對(duì)象了。
document對(duì)象又掛載在window對(duì)象上,所以在瀏覽器就可以直接訪問(wèn)document了。
老規(guī)矩,先講講document對(duì)象的屬性,等會(huì)講講它的方法。
document對(duì)象上的一些屬性
document.childNodes 繼承自上面講的Node類型,可以返回文檔的直接子節(jié)點(diǎn)(通常包括文檔聲明和html節(jié)點(diǎn))
document.documentElement 可以直接拿到html節(jié)點(diǎn)的引用(等價(jià)于document.getElementsByTagName("html")[0])。
document.body body節(jié)點(diǎn)的引用
document.title ?頁(yè)面的title,可以修改,會(huì)改變?yōu)g覽器標(biāo)簽上的名字
document.URL 頁(yè)面的url
document.referrer 取得referrer,也就是打開(kāi)這個(gè)頁(yè)面的那個(gè)頁(yè)面的地址,做來(lái)源統(tǒng)計(jì)時(shí)候比較有用
document.domain 取得域名,可以設(shè)置,但是通常只能設(shè)置為不包含子域名的情況,在一些子域名跨域情況下有效。
接下來(lái)介紹兩個(gè)熟悉的方法
getElementById 和 getElementsByTagName
getElementById,傳入id,得到元素節(jié)點(diǎn)。里面的參數(shù)區(qū)分大小寫(IE8-不區(qū)分)。注意:如果有多個(gè)id相同的元素,則返回第一個(gè)。IE7-里面表單元素的name也會(huì)被當(dāng)做id來(lái)使用。
getElementsByTagName 根據(jù)標(biāo)簽取得元素,得到的是HTMLCollection類型。如果傳入的是 "*" ,則可以取得全部元素。
還有一個(gè)是只有HTMLDocument類型(也就是document對(duì)象)才有的方法 getElementsByName 顧名思義,根據(jù)name返回元素。
document對(duì)象還有一些集合,例如document.forms 可以返回所有的form表單。類型也是HTMLCollection。
說(shuō)到HTMLCollection,就再說(shuō)說(shuō)它
HTMLCollection就是一個(gè)包含一個(gè)或多個(gè)元素的集合,和上面講的NodeList還挺像的。HTMLCollection這個(gè)類型有兩個(gè)方法,一個(gè)是通過(guò)下標(biāo)(或者.item())得到具體元素,還有就是通過(guò)['name'](或者.namedItem())獲得具體元素。
最后,關(guān)于document對(duì)象還有一套重要的方法,那便是
write() writeln() open() close()
open和close分別是打開(kāi)和關(guān)閉網(wǎng)頁(yè)的輸出流,在頁(yè)面加載過(guò)程中,就相當(dāng)于open狀態(tài)。這兩個(gè)方法一般不會(huì)去用它。
然后重要的方法就是write和writeln,它們都是向頁(yè)面寫入東西,區(qū)別就是后者會(huì)多加入一個(gè)換行符。
注意的是:在頁(yè)面加載的過(guò)程中,可以使用這兩個(gè)方法向頁(yè)面添加內(nèi)容。如果頁(yè)面已經(jīng)加載完了,再調(diào)用write,會(huì)重寫整個(gè)頁(yè)面。
還有一點(diǎn),如果要?jiǎng)討B(tài)寫入腳本 例如 <script>xxx</script>這樣的 ,那么要注意把</script>分開(kāi)來(lái)拼裝下,否則會(huì)被誤以為是腳本結(jié)束的標(biāo)志,導(dǎo)致這個(gè)結(jié)束符匹配到上面一個(gè)開(kāi)始符??梢赃@樣寫"<scr" + "ipt>";
四、Element類型
接下來(lái)講講最重要也是最常見(jiàn)的一個(gè)類型,Element類型。
我們?nèi)粘K僮鞯亩际荅lement類型(實(shí)質(zhì)是HTMLElement,這里為了方便理解,就簡(jiǎn)單這么說(shuō)),比如
document.getElementById("test")返回的就是Element類型。我們?nèi)粘Kf(shuō)的“DOM對(duì)象”,通常也就是指Element類型的對(duì)象。
然后說(shuō)說(shuō)這個(gè)類型的常見(jiàn)屬性:
首先最開(kāi)始說(shuō)的Node類型上的那些屬性方法它都有,這個(gè)就不再重復(fù)了,主要說(shuō)說(shuō)它自己獨(dú)有的。
首先是tagName,這個(gè)和繼承自Node類型的nodeName一樣。都是返回標(biāo)簽名,通常是大寫,結(jié)果取決于瀏覽器。所以在做比較
的時(shí)候最好是調(diào)用下類似toLowerCase()這種方法再做比較。
說(shuō)說(shuō)上面提到過(guò)的HTMLElement類型
HTMLElement類型繼承自Element類型,也是HTML元素的實(shí)際類型,我們?cè)跒g覽器里用的元素都是這個(gè)類型。
這個(gè)類型都具有一些標(biāo)準(zhǔn)屬性,比如:
id 元素的唯一標(biāo)識(shí)
title 通常是鼠標(biāo)移上去時(shí)候會(huì)顯示的信息
className 類名
等等,這幾個(gè)屬性是可讀寫的,也就是說(shuō)你改變他們會(huì)得到相應(yīng)的效果。
除了屬性外,還有幾個(gè)重要的方法
首先說(shuō)說(shuō)操作節(jié)點(diǎn)屬性的方法
getAttribute 、setAttribute 、removeAttribute這3個(gè)方法。
這些是操作屬性最常用的方法了,怎么用就不說(shuō)了,很簡(jiǎn)單,顧名思義。
還有一個(gè)attributes屬性,保存了元素的全部屬性。
這里停下來(lái),出個(gè)問(wèn)題,ele.className 和 ele.getAttribute("class")返回的結(jié)果是不是同一個(gè)東西?
解答這個(gè)問(wèn)題,我要說(shuō)一個(gè)重要知識(shí)點(diǎn),一個(gè)元素的屬性結(jié)構(gòu)是這么來(lái)的,比如一個(gè)inpnt元素
<input id="test" checked="checked">那么這個(gè)元素的屬性被包含在 input.attributes里面,比如你在html元素上看到的class、id或者你自己定義的data-test這種屬性。
然后?getAttribute 、setAttribute 、removeAttribute這3個(gè)方法可以認(rèn)為是快捷的取attributes集合的方法。而直接input.id或者input.className都是直接掛在input下的屬性,和attributes是同級(jí)的。所以返回的東西也許看過(guò)去一樣,實(shí)際是不一樣的,不信你可以試試input.checked這input.getAttribute("checked")試試。
關(guān)于這個(gè)知識(shí)點(diǎn),詳細(xì)的說(shuō)可以再寫一篇文章,在我的博客?從is(":checked")說(shuō)起?中有談到過(guò),大家可以看看這篇文章和文章后的討論,便可以知道是怎么一回事。
總得來(lái)說(shuō),這3個(gè)方法通常用了處理自定義的屬性,而不是id、class等這種“公認(rèn)特性”。
接下來(lái)說(shuō)說(shuō)創(chuàng)建元素
document.createElement()可以創(chuàng)建一個(gè)元素,比如:
document.createElement("div");一般之后可以為元素設(shè)置屬性,兩種方法,一種是直接node.property還可以node.setAttribute("propertyName","value")。等
但是做完這些之后,這個(gè)元素還是沒(méi)有在頁(yè)面中,所以你還得通過(guò)最上面講的類似appendChild這些方法把元素添加到頁(yè)面里面。
在IE中,還可以直接穿整個(gè)HTML字符串進(jìn)去,來(lái)創(chuàng)建元素,比如
document.createElement("<div>test</div>");最后,元素節(jié)點(diǎn)也支持HTMLDocument類型的那些查找方法,比如getElementsByTagName。不過(guò)它只會(huì)找自己后代的節(jié)點(diǎn)。所以可以這么寫代碼
document.getElementById("test").getElementsByTagName("div"); // 找到id為test元素下的所有div節(jié)點(diǎn)五、Text類型
這個(gè)類型很特殊,也是第三常見(jiàn)類型(第一第二分別就是Document和Element)。
這個(gè)節(jié)點(diǎn)簡(jiǎn)單來(lái)說(shuō)就是一段字符串。
有個(gè)很重要的特征就是,它沒(méi)有子元素(不過(guò)這個(gè)仔細(xì)想想也知道= =)
訪問(wèn)text節(jié)點(diǎn)的文本內(nèi)容,可以通過(guò)nodeValue或者data屬性。
下面簡(jiǎn)單說(shuō)說(shuō)它提供的一些方法
appendData(); // 在text末尾加內(nèi)容 deleteData(offset, count); // 從offset指定的位置開(kāi)始刪除count個(gè)字符還有insertDate、replaceData、splitText等方法,就不一一說(shuō)了,用的機(jī)會(huì)很少,可以用的時(shí)候再查閱。
然后它還有一個(gè)lenght屬性,返回字符長(zhǎng)度的。
這里說(shuō)一個(gè)常見(jiàn)的坑。比如下面這個(gè)html結(jié)構(gòu)
<ul><li></li><li></li> </ul>這里,ul的第一個(gè)子節(jié)點(diǎn)(firstChild)是什么呢?第一眼看過(guò)去,肯定認(rèn)為是li了,但是實(shí)際上,你會(huì)發(fā)現(xiàn)不是li,而是一個(gè)文本節(jié)點(diǎn)!
這是因?yàn)闉g覽器認(rèn)為ul和第一個(gè)li之間有空白字符,所以就有文本節(jié)點(diǎn)了。
這里一個(gè)常見(jiàn)的問(wèn)題就是遍歷ul的childNodes的時(shí)候,遍歷的元素一定要判斷下nodeType是不是等于1(等于1就代表是元素節(jié)點(diǎn)),這樣才能跳過(guò)這個(gè)坑。否則你也可以刪除所有的空格和換行符。
創(chuàng)建文本節(jié)點(diǎn)的方法是document.createTextNode
然后接下來(lái)和操作Element類型一樣,就是再插入到元素中,瀏覽器就可以看到了。
六、其他的一些類型 Comment、DocumentType和DocumentFragment
這些不常用的一句話帶過(guò)把
Comment是注釋節(jié)點(diǎn)
DocumentType就是doctype節(jié)點(diǎn),通過(guò)docment.doctype來(lái)訪問(wèn)
DocumentFragment這個(gè)節(jié)點(diǎn)是一個(gè)文檔片段,偶爾會(huì)用到。
比如一種常見(jiàn)的用法是,在一個(gè)ul中插入3個(gè)li。
如果你循環(huán)插入3次,那么瀏覽器就要渲染3次,對(duì)性能有蠻大的影響。
所以大家一般這么做
先
var fragment = document.createDocumentFragment();然后循環(huán)把li,用appendChild插入到fragment里面
最后在一次把fragment插入到ul里面。這樣就會(huì)很快。
七、DOM擴(kuò)展
進(jìn)過(guò)上面講的這么多節(jié)點(diǎn)類型,想必大家對(duì)DOM節(jié)點(diǎn)已經(jīng)有了很深的了解,下面講一講DOM擴(kuò)展的一些東西。
瀏覽器為了方便開(kāi)發(fā)者,擴(kuò)展了一些DOM功能。
因?yàn)槭菫g覽器自己擴(kuò)展的,所以使用前兼容性問(wèn)題一定要注意
判斷“標(biāo)準(zhǔn)模式”和“混雜模式”通過(guò) document.compatMode和新的document.documentMode
上面不是說(shuō)了一個(gè)文本節(jié)點(diǎn)作為第一子元素的坑嗎,所以瀏覽器又實(shí)現(xiàn)了一個(gè)children屬性,這個(gè)屬性只包含元素節(jié)點(diǎn)。
為了方便判斷A節(jié)點(diǎn)是不是B節(jié)點(diǎn)的子節(jié)點(diǎn),引入了contains方法,比如?
B.contains(A); // true就代表是,false就代表不是這個(gè)方法有兼容性問(wèn)題,使用前可以谷歌解決方法。
針對(duì)訪問(wèn)元素,又提供了4個(gè)方法innerText/innerHTML/outerTEXT/outerHTML。
通過(guò)這些方法,可以讀和寫元素。
其中,*TEXT是返回文本內(nèi)容?*HTML是返回html文本。
而outer*則是代表是否包含元素本身。
實(shí)際使用來(lái)看,在讀內(nèi)容的時(shí)候 inner*和outer*沒(méi)有區(qū)別。
在把內(nèi)容寫入元素的時(shí)候,就是是否包含元素本身的區(qū)別。
重要的是,這幾個(gè)方法有性能問(wèn)題,比如在IE中,通過(guò)inner*刪除的節(jié)點(diǎn),其綁定的事件依然在內(nèi)存中,就很容易消耗大量?jī)?nèi)存。
還有一個(gè)技巧是,插入大量的html代碼,用innerHTML是非??斓?#xff0c;建議使用。
八、總結(jié)
首先感謝所有看到這里的朋友,哈哈,關(guān)于DOM的東西實(shí)在是太多了,不過(guò)這也算是最重要的一個(gè)前端知識(shí)點(diǎn)之一吧。文章比較長(zhǎng),也許有點(diǎn)乏味,不過(guò)希望你們耐著性子看完后可以有所收貨^ ^。
QQ群:?WEB開(kāi)發(fā)者官方總?cè)?515171538)?驗(yàn)證消息:Admin10000 提示:常上QQ空間的朋友可關(guān)注【W(wǎng)EB開(kāi)發(fā)者】騰訊認(rèn)證空間,精彩內(nèi)容不錯(cuò)過(guò)。 DOM 相關(guān)文檔- 為什么說(shuō)DOM操作很慢
- 寫一個(gè)更好的Javascript DOM庫(kù)
- DOM事件簡(jiǎn)介
- 也許 DOM 不是答案
- 2016年你應(yīng)該學(xué)習(xí)的語(yǔ)言和框架
- 如何選擇大數(shù)據(jù)的編程語(yǔ)言
- C#集合類型大盤點(diǎn)
- 我們?cè)谑褂胘Query的時(shí)候,到底在使用
- 最全面的 DNS 原理入門
- 高級(jí)PHP工程師所應(yīng)該具備一些技能
- 44個(gè) Javascript 變態(tài)題解析
- 為什么說(shuō)每個(gè)程序員都應(yīng)該有臺(tái)Mac電腦
- 買蘋果設(shè)備需要注意哪些坑
- 為什么我要寫自己的框架?
- 2015年需要了解的前端框架和語(yǔ)言
- Top 10:HTML5、JavaScript 3D游戲引擎和框架
- Web前端知識(shí)技能大匯總
- WEB前端知識(shí)在亂花漸欲迷人眼的當(dāng)下,如何分清主次和學(xué)習(xí)優(yōu)先級(jí)呢?
- 無(wú)聊的前端工程師
- 前端的黑客精神
- 2016 年后 Web開(kāi)發(fā)趨勢(shì)是什么
- 2016九大前端必備動(dòng)畫庫(kù)
- 前端跨域的整理
- GET和POST有什么區(qū)別?及為什么網(wǎng)上的多數(shù)答案都是錯(cuò)的。
- 如何通過(guò)預(yù)加載器提升網(wǎng)頁(yè)加載速度
- 值得收藏的14款響應(yīng)式前端開(kāi)發(fā)框架
- 直接拿來(lái)用!最火的前端開(kāi)源項(xiàng)目(一)
- 給網(wǎng)頁(yè)設(shè)計(jì)師和前端開(kāi)發(fā)者看的前端性能優(yōu)化
- 網(wǎng)頁(yè)圖片優(yōu)化的實(shí)用工具和技巧分享
- 每個(gè)開(kāi)發(fā)人員都應(yīng)該知道五個(gè)設(shè)計(jì)技巧
- 如何做一個(gè)好重構(gòu)
- 網(wǎng)頁(yè)編碼就是那點(diǎn)事
- 我需要支持IE6么?
- WEB開(kāi)發(fā)中合理選擇圖片格式
- 15個(gè)實(shí)用的HTML5、JS工具和jQuery插件
- 15個(gè)最好的Bootstrap設(shè)計(jì)工具推薦
- 利用 Bootstrap 進(jìn)行快速 Web開(kāi)發(fā)
- 前端模塊管理器簡(jiǎn)介
- FckEditor(CKEditor)配置詳細(xì)教程
- 前端工程師必備技能匯總
- 網(wǎng)易財(cái)經(jīng)前端開(kāi)發(fā)總結(jié)
- 前端跨域的整理
- 透過(guò)瀏覽器看HTTP緩存
- 為什么整個(gè)互聯(lián)網(wǎng)行業(yè)都缺前端工程師?
小豬CMS(PigCms)源碼全網(wǎng)一家
微信營(yíng)銷源碼突破微信公眾平臺(tái)限制 無(wú)限自定義圖文回復(fù).打造具營(yíng)銷企業(yè)網(wǎng)站.
?
去看看 X總結(jié)
以上是生活随笔為你收集整理的DOM 之通俗易懂讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SQL JOIN的用法
- 下一篇: 通过反射将变量值转为变量名本身