本文主要是整理DOM相關的知識點,方便往後的查看和各位的查缺補漏。因此重在整理,並不會展開。目前還在持續整理中,打算在16日左右完結。css
nodeTypehtml
Node.nodeType// 1爲元素節點,2爲屬性節點,3爲文本節點
nodeName與tagNamenode
elementName = Element.tagName;//返回爲大寫標籤名,如DIV,IMG。通常用tagName便可。 * Attr ------ Attr.name 屬性名 * Element ------ Element.tagName 標籤名 * Text ------ nodeName爲‘#text’,tagName爲undefined
nodeValuejquery
* Text ------ 文本內容 * Element ------ null
//返回的是NamedNodeMap,不是ARRY。NamedNodeMap是字符串形式的名/值對。無序,且可自動更新。 //獲取參照mdn var attr = element.attributes; ```
-方法:segmentfault
Node.hasChildNodes() // 若是包含子節點就返回true
DOM節點(Node)一般對應於一個標籤,一個文本,或者一個HTML屬性。DOM節點有一個nodeType屬性用來表示當前元素的類型,它是一個整數:數組
DOM節點建立最經常使用的即是document.createElement和document.createTextNode方法:瀏覽器
var el1 = document.createElement('div'); var node = document.createTextNode('hello world!');
getElementsByTagName等返回的實時的元素集合不須要預先得到全部的元素信息,而.querySelectorAll()會馬上收集全部的信息到一個靜態的列表裏,於是會[下降性能][2]。 能夠用instanceof操做符檢查節點的原型鏈: ``` myElement.firstChild.nodeType instanceof Text ```
元素查詢的API返回的的結果是DOM節點或者DOM節點的列表。app
//相似於css選擇器: 選擇classA下的classb元素 document.querySelector(".classA .classB"); // 返回選擇的第一個元素.myEl var el = myEl.querySelector("#foo > div.bar"); // 返回一個文檔中a static NodeList,不是即時的 var els = myEl.querySelectorAll(".class"); //元素是否匹配選擇器 myElement.matches('div.bar') === true // 返回的是HTMLCollection,即時更新的。 var el = document.getElementById('ID'); var els = document.getElementsByClassName('CLASS'); var els = document.getElementsByTagName('標籤名'); var els = document.getElementsByName('name屬性');
Element也提供了不少相對於元素的DOM導航方法:dom
// 獲取父元素、父節點 var parent = ele.parentNode; var parent = ele.parentElement;//非標準 // 獲取子節點,子節點能夠是任何一種節點,能夠經過nodeType來判斷 var nodes = ele.children;//元素節點 var nodes = ele.childNodes; //全部節點,包括文本,元素等。可配合nodeType == 1獲得元素節點 // 當前元素的第一個/最後一個子元素節點 ele.firstElementChild;//第一個元素節點 ele.firstChild //第一個節點,通常是文本節點 ele.lastElementChild;//最後一個元素節點 ele.lastChild//最後一個節點 // 下一個/上一個兄弟節點 var el = ele.nextElementSibling;//元素節點 var el = ele.nextSibling;//包括文本節點 var el = ele.previousElementSibling; var el = ele.previousSibling;
append,replace,insertBefor的參數el若是已存在DOM中,都會先移除,再插入到新位置。
刪除一個元素自身
myElement.parentNode.removeChild(myElement)
// 添加、刪除子元素.屢次appendChild到一個父節點會引發瀏覽器屢次從新渲染,此時能夠將節點組合到fragment = document.createDocumentFragment()中。 ele.appendChild(el);//避免鏈式操做 ele.removeChild(el);//若是有返回值,則存在內存中。 // 替換子元素 //newChild若是存在dom中,則會被移除。replaceNode 爲oldChild replaceNode = parentNode.replaceChild(newChild, oldChild); // 插入子元素 //newElement若是存在dom中,會先被移除再插入(不想移除可先複製)。 //referenceElement必須有,可爲null,爲null時,插入到parentElement最後 //return新增長的node(fragment不返回) newElement = parentElement.insertBefore(newElement, referenceElement); //沒有insertAfter parentElement.insertBefore(newElement,referenceElement.nextSibling) //prepend,使用insertBefore代替。 ParentNode.prepend(nodesToPrepend); //IE支持很差 parentElement.insertBefore(newElement, theFirstChild);//jquery中prepend()也是用此方法 //克隆節點 //node須要被克隆的node //deep爲ture,則克隆全部子節點。deep不要省略,由於各版本瀏覽器默認值不一樣。 //深度克隆會克隆全部屬性(除addEventListener和後續添加的click事件如:node.onclick = fn,可是會克隆寫在dom中的onclick事件),容易致使id重複的問題。 var dupNode = node.cloneNode([deep]); //document和iframe之間的克隆 var node = document.importNode(externalNode, deep);
.getAttibute(), .setAttribute()和.removeAttribute()這三個方法。這些方法直接修改的是元素的HTML屬性(與DOM屬性相對),所以會使瀏覽器從新渲染。瀏覽器從新渲染不只比只是設置DOM屬性代價更高,並且還會產生不指望的後果。做爲一個小原則,除非你真的想對HTML「持久化」那些改變,你就只用上面的方法修改與DOM屬性不相關的HTML屬性(好比colspan)
// 獲取一個{name, value}的數組 var attrs = el.attributes; // 獲取、設置屬性 var c = el.getAttribute('class'); el.setAttribute('class', 'highlight'); // 判斷、移除屬性 el.hasAttribute('class'); el.removeAttribute('class'); // 是否有屬性設置 el.hasAttributes(); // Get an attribute value const value = myElement.value // Set an attribute as an element property myElement.value = 'foo' // Set multiple properties using Object.assign() Object.assign(myElement, { value: 'foo', id: 'bar' }) // Remove an attribute myElement.value = null
className和classList
myElement.classList.add('foo') myElement.classList.remove('bar') myElement.classList.toggle('baz') el.className += ' class'
在JavaScript裏要寫成駝峯形式.若是咱們想得到CSS規則的值,咱們能夠經過.style屬性。然而,經過它只能拿到咱們明確設置過的樣式。想拿到計算後的樣式值,咱們能夠用.window.getComputedStyle()。它能夠拿到這個元素並返回一個CSSStyleDeclaration。這個返回值包括了這個元素本身的和繼承自父元素的所有樣式。
myElement.style.marginLeft = '2em' window.getComputedStyle(myElement).getPropertyValue('margin-left') // 動態添加樣式規則 var style = document.createElement('style'); style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}'; document.head.appendChild(style);
DOM元素的innerHTML, outerHTML, innerText, outerText屬性的區別也常常被面試官問到, 好比對於這樣一個HTML元素:
<div id="main"> 我是測試文本<br/> </div>
let el = document.querySelector("#main"); console.log("el.innerHTML: ",el.innerHTML); //我是測試文本<br> console.log("el.outerHTML: ",el.outerHTML); //<div id="main">我是測試文本<br></div> console.log("el.innerText: ",el.innerText); //我是測試文本 console.log("el.outerText: ",el.outerText); //我是測試文本 /* el.innerText = "哈哈"; */ el.outerText = "哈哈";
outerText:內部文本;
上述四個屬性不只能夠讀取,還能夠賦值。outerText和innerText的區別在於outerText賦值時會把標籤一塊兒賦值掉,另外xxText賦值時HTML特殊字符會被轉義。
https://jsfiddle.net/langlang...
jQuery的.html()會調用.innerHTML來操做,但同時也會catch異常,而後用.empty(), .append()來從新操做。 這是由於IE8中有些元素的.innerHTML是隻讀的。見:http://stackoverflow.com/ques...
NodeList 和 HTMLCollection區別。
NodeList是節點集合,包括任何節點類型。HTMLCollection是元素集合。NodeList有.forEach(),但IE不支持,因此通常轉換成數組再調用
//[Arry.from()][5] Array.from(myElements).forEach(doSth); Array.protoType.forEach.call(myElements,doSth); [].forEach.call(myElements,doSth)
參考文章: