国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Javascript--DOM

jsyzchen / 1397人閱讀

摘要:中的所有對象都是以對象的形式實現的。這意味著中的對象與原生對象的行為或活動特點并不一致。該屬性指向表示整個文檔的文檔節點。同時由要插入的節點占據其位置。返回被移除的節點。操作類名操作類名時,需要通過屬性添加刪除和替換類名。

Note:IE中的所有DOM對象都是以COM對象的形式實現的。這意味著IE中的DOM對象與原生Javascript對象的行為或活動特點并不一致。

DOM1級主要定義了HTML和XML的文檔的底層結構。DOM2和DOM3級分為幾個模塊。

DOM2級核心(DOM Level 2 Core):在1級核心基礎上構建,為節點添加了更多方法和屬性

DOM2級視圖(DOM Level 2 Views):為文檔定義了基于樣式信息的不同視圖

DOM2級事件(DOM Level 2 Events):說明了如何使用事件與DOM文檔交互

DOM2級樣式(DOM Level 2 Style):定義了如何以編程方式來訪問和改變CSS樣式信息

DOM2級遍歷和范圍(DOM Level 2 Tranversal and Range):引入了遍歷DOM文檔和選擇其特定部分的新接口。

DOM2級HTML(DOM Level 2 HTML):在1級HTML基礎上構建,添加了更多屬性、方法和新街口。

// 判斷是否支持模塊
var DOM2Core = document.implementation.hasFeature("Core",2.0)
DOM2級核心 Node
DOM1級定義了一個Node接口。該接口將由DOM中的所有節點類型實現。
Javascript中的所有節點類型都 繼承自Node類型,因此所有節點類型都共享著相同的基本屬性和方法。

兼容性:除IE外,其他所有瀏覽器都可以訪問到這個類型

節點類型
每個節點都有一個nodeType屬性,用于表明節點的類型。
節點類型由在Node類型中定義的12個數值常量來表示,下面列出常用的幾個。

Node.ELEMENT_NODE: 1

Node.TEXT_NODE: 3

Node.COMMENT_NODE: 8

節點信息
可以通過nodeNamenodeValue來了解節點信息。這兩個屬性取決于節點的類型。
在使用這兩個節點之前,最好先檢測一下節點類型。

如果節點是一個元素,nodeName中保存的始終是元素的標簽名,而nodeValue值始終為0。

節點關系
每個節點都有一個childNodes屬性,其中保存著一個NodeList對象。NodeList對象是一種類數組對象,用于保存一組有序的節點,可以通過位置來訪問這些節點。

hasChildNodes():這個方法在節點包含一個或多個子節點的情況下返回true。
ownerDocument:該屬性指向表示整個文檔的文檔節點。
// 將NodeList對象轉換為數組
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);

兼容性:IE8以及更早版本將NodeList實現為一個COM對象,因此上面的代碼會導致錯誤。

Note:NdoeList對象的特殊之處在于,它實際上是基于DOM結構動態執行查詢的結果,因此DOM的變化能直接反映在NodeList對象之中。它是有生命的對象,而不是在我們第一次訪問它在某一個瞬間拍下的快照。

操作節點

appendChild():用于向childNodes列表的末尾添加一個節點。返回新增的節點。

insertBefore():接收兩個參數:要插入的節點和作為參照的節點。插入節點后,被插入的節點會變成參照節點的前一個同胞節點。同時被方法返回。

replaceChild():接收兩個參數:要插入的節點和要替換的節點。要替換的節點將由這個方法返回并從文檔樹中移除。同時由要插入的節點占據其位置。

removeChild():接收一個參數,即要移除的節點。返回被移除的節點。

這四個方法都是操作的某個節點的子節點,也就是說,要使用這幾個方法必須先取得父節點。另外并不是所有節點都有子節點,如果在不支持子節點的節點上,調用了這些方法,將會導致錯誤。

Note:

如果傳入到appendChild()中的節點已經是文檔的一部分,那結果就是將該節點從原來的位置轉移到新位置。即可以將DOM樹看成是由一系列指針連接起來的,但任何DOM節點也不能同時出現在文檔中的多個位置上。

在使用replaceChild()插入一個節點時,該節點的關系指針都會從被它替換的節點復制過來。從技術上來講,被替換的節點仍然還在文檔中,但它在文檔中已經沒有了自己的位置。同樣的,removeChild()移除的節點也同樣為文檔所有,只不過在文檔中已經沒有了自己的位置。

其他方法
有兩個方法是所有類型節點都要的。

cloneNode():用于創建調用這個方法的節點的一個完全相同的副本。接收一個布爾值參數,true:表示執行深復制,也就是復制節點以及整個子節點樹。false:表示執行淺復制,即只復制節點本身。

  • item 1
  • item 2
  • item 3
var myList = document.body.childNodes[1]; var deepList = myList.cloneNode(true); //3 (IE < 9)或7(其他瀏覽器) console.log(deepList.childNodes.length); // 使用childNodes屬性的建議 for (var i =0; i < ele.childNodes.length; i++){ if(childNodes[i].nodeType === 1) { // 執行某些操作 } }

Note:

deepList.childNodes.length中的差異主要是因為IE8以及更早版本與其他瀏覽器處理空白字符的方式不一樣。IE9以及之前版本不會為空白符創建節點。

cloneNode()方法不會復制添加到DOM節點中的Javascript屬性,例如事件處理程序等。這個方法只復制特性,在明確指定的情況下也復制子節點,其他一切都不會復制。IE在此存在一個bug,即它會復制事件處理程序,所以建議,在復制之前最好先移除事件處理程序。

normalize():處理文檔樹種的文本節點。

Document類型--nodeType=9
Javascript通過Document類型表示文檔。HTMLDocument繼承自Document類型
1.document對象是HTMLDocument對象的實例
2.document對象是window對象的一個屬性,可以將其作為全局對象進行訪問。
document instanceof HTMLDocument //true
HTMLDocument.__proto__ ==== Document //true

document作為我們操作文檔的一個公共接口存在。

document信息

document.URL:包含頁面完整的URL

document.domain:包含頁面的域名

document.referrer:保存著鏈接到當前頁面的那個頁面的URL

在這三個屬性中只有domain是可以設置的。但由于安全方面的限制,也并非可以給domain設置任何值。

不能將這個屬性設置為URL中不包含的域

如果域名一開始是松散的,那么不能將它設置為緊繃的。

// 假設頁面來自p2p.wrox.com域
document.domain = "wrox.com"; // 松散的,成功
document.domain = "nczonline.ne4t" // 出錯
document.domain = "p2p.wrox.com"   // 緊繃的,出錯

document.readyState:有兩個可能的值(HTML5新增)

loading:正在加載文檔

complete:已經加載完文檔

document.compatMode:這個屬性的作用是告訴開發人員瀏覽器采用了那些渲染模式(HTML5新增)

值等于"CSS1Compat",表明瀏覽器采用標準模式進行渲染

值等于"BackCompat",表明瀏覽器在混雜模式下進行渲染

document子節點

document.documentElement:獲得html元素的引用

document.body:獲得body元素的引用

document.head:獲得head元素的引用(HTML5新增)

document.title:包含title元素的中的文本

document.activeElement:這個屬性始終會引用DOM中當前獲得了焦點的元素(HTML5新增)

Browser compatibility-head
Browser compatibility-activeElement

查找節點(元素節點)
Document類型為查元素提供了兩種方法,1,2
HTMLDocument類型提供了方法,3

document.getElementById()

document.getElementsByName:這個方法會返回帶有給定name特性的元素,最常用于取得單選按鈕。同樣也返回 HTMLCollection對象。

HTMLCollection對象,可以通過length屬性訪問元素長度,通過[]方括號語法訪問對象中的項。方括號中既可以是數字也可以是字符串的索引值。

創建節點

document.createElement():接收一個參數,即要創建元素的標簽名。
document.createTextNode():接收一個參數,要插入節點中的文本。

特殊集合
這些集合都是HTMLCollection對象

document.anchors:包含文檔中帶name特性的>元素

document.forms:包含文檔中所有的

元素

document.images:包含文檔中所有的元素

document.links:包含文檔中所有帶href特性的a元素

Element類型--nodeType=1
Element類型用于表現HTML或XML元素。HTMLElement類型繼承自Element類型。并添加了一些屬性。

HTMLElement.__proto__ === Element// true

屬性
讀取

添加的屬性:可讀也可寫

id

title

lang(很少使用)

dir(很少使用)

className:與元素的class特性對應。

dataset:HTML5規定可以為元素添加非標準的屬性,但要添加前綴data-,目的是為元素提供與渲染無關的信息,或者提供語義信息。這些屬性可以任意添加,隨機命名,只要以data-開頭即可。可以通過元素的dataset屬性來訪問自定義屬性

    
var div = document.getElementById("bd"); console.log(div.id); console.log(div.className); console.log(div.title); console.log(div.lang); console.log(div.dir);
相關方法

getAttribute():一般只有在取自定義特性情況下,才會使用此方法

setAttribute():接收兩個參數,要設置特性的特性名和值

removeAttribute():用于徹底刪除元素的特性

DOM methods dealing with element"s attributes:

attributes屬性
attributes屬性中包含一個NamedNodeMap,與NodeList類似。
通常用于遍歷元素的特性。
function outputAttributes ( ele ) {
    var pairs = [],
    attrName,
    attrValue,
    i,
    len;

    for(i = 0; i < ele.attributes.length; i++) {
        attrName = ele.attributes[i].nodeName;
        attrValue = ele.attributes[i].nodeValue;
        pairs.push(attrName + "=" + attrValue + """)
    }
    pairs.join("");
}
操作類名
操作類名時,需要通過className屬性添加、刪除、和替換類名。因為className是一個字符串,所以即使只修改字符串一部分,也必須每次都設置整個字符串的值。
    
// 刪除"user"類 // 首先取得類名字字符并拆分成數組 var div = document.getElementsByTagName("div")[0]; var className = div.className.split(/s+/); // 找到要刪的類名 var pos = -1, i, len for(i = 0,len = className.length;i < len;i++) { if(className[i] === "user") { pos = i; break; } } className.splice(i,1); // 把剩下的類名拼成字符串并重新設置 div.className = className.join(" ");

為了從div中刪除class屬性中的"user",以上這些代碼都是必須的。很多javascript都實現了這個方法,以簡化這些操作

classList
HTML5新增了一個操作類名的方式,可以讓操作更簡單也更安全。那就是為所有元素添加classList這個屬性。這個classList屬性是新集合類型DOMTokenList的實例。這個屬性是只讀的,有一個表示自己包含多少元素的length屬性,而要取得每個元素可以使用item()方法,也可以使用方括號語法。如果你想修改classList屬性,那么可以通過它定義的以下幾個方法進行修改。

add(value):將給定的字符串值添加到列表中。如果值已經存在,就不添加了

remove(value):從列表中刪除給定的字符串

contain(value):表示列表中是否存在給定的值,如果存在則返回true,不存在返回false

toggle(value):如果列表中已經存在給定的值,刪除它;如果列表中沒有給定的值,添加它

Browser Compatibility

插入標記(HTML5新增)
insertAdjacentHTML():接收兩個參數,插入位置和要插入的HTML文本

第一個參數必須是下列值之一:

beforebegin:在當前元素之前插入一個緊鄰的同輩元素

afterbegin:在當前元素之下插入一個新的子元素或在第一個子元素之前再插入新的子元素

beforeend:在當前元素之下插入一個新的的子元素或在最后一個子元素之后插入新的子元素

afterend:在當前元素之后插入一個緊鄰的同輩元素

瀏覽器兼容性

Text類型--nodeType=3
包含的是可以照字面意思接收的純文本內容。

HELLO WORLD!
合并文本節點
DOM文檔中存在相鄰的同胞文本節點很容易導致混亂,因為分不清哪個文本節點表示哪個字符串。

瀏覽器在解析文檔時,永遠不會創建相鄰的文本節點。

出現相鄰的文本節點只會作為執行DOM操作的結果出現

如果在一個包含兩個或多個文本節點的父元素上調用,Node類型的normalize()方法,則會將所有文本節點合并成一個節點。

var ele = document.createElement("div");
var text1 = document.createTextNode("Hello World!");
var text2 = document.createTextNode("Hi");
ele.appendChild(text1);
ele.appendChild(text2);

document.body.appendChild(ele)

console.log(ele.childNodes.length);// 2
ele.normalize();
console.log(ele.childNodes.length);// 1
分割文本節點
splitText():這個方法會將一個文本節點分成兩個文本節點,即按照指定的位置分割nodeValue值。
var ele = document.createElement("div");
var text = document.createTextNode("Hello World!");
ele.appendChild(text);

document.body.appendChild(ele)

var newNode = ele.firstChild.splitText(5);
console.log(newNode.nodeValue);// " World"
操作表格
// 創建table
var table = document.createElement("table");
table.border = 1;
table.width = "100%";

// 創建tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);

// 創建第一行
tbody.insertRow(0);
tbody.rows[0].insertCell(0);
tbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1.1"));
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2.1"));

// 創建第二行
tbody.insertRow(1);
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 1.2"));
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2.1"));

// 添加到文檔中
document.body.appendChild(table);
選擇符API
可以通過Document類型和Element類型的實例調用他們。

1.querySelector()
2.querySelectorAll()

Browser Compatibility-querSelector
Browser Compatibility-querSelectorAll

Note:

不像如getElementsByTagName這樣的API, 通過以上兩個API返回的對象不是live的。也就是說當文檔改變的時候,他們不會改變。

具體來說,返回的值實際上是帶有所有屬性和方法的NodeList,而其底層實現則類似于一組元素的快照,而非不斷對文檔進行搜索的 動態查詢。這樣實現可以避免使用NodeList對象通常會引起的大多數性能問題

3.document.getElementsByTagName():返回包含0或多個元素的NodeList。在HTML文檔中,這個方法會返回一個 HTMLCollection對象,作為一個動態集合,該對象與NodeList非常相似。

4.getElementsByClassName():返回HTMLCollection對象,所以使用這個方法與使用getElementsByTagName()以及其他返回NodeList的DOM方法具有同樣的性能問題

Browser Compatibility

關于NodeList
NodeList及其近親NameNodeMap和HTMLCollection這個三個集合都是動態的。也就是說每當文檔結構發生變化,他們都會得到更新。
本質上:NodeList對象是在訪問DOM文檔時實時運行的查詢。
性能影響

DOM操作往往是Javascript程序中開銷最大的部分,而因訪問NodeList導致的問題最大。一般來說,盡量減少訪問NodeList的次數。因為每次訪問NodeList,都會運行一次基于文檔的查詢。所以,可以考慮將從NodeList取得的值緩存起來。或者盡量減少DOM操作

DOM2級遍歷和范圍 元素遍歷
對于元素間的空格,IE9以及之前不會返回文本節點,而其他所有瀏覽器都會返回文本節點。這樣就導致了在使用childNodes和firstChild等屬性時的行為不一致。為了彌補這一差異。

Element Tranversal API為DOM元素添加了以下5個屬性

childElementCount:返回子元素(不包括文本節點和注釋)的個數

firstElementChild:指向第一個子元素;firstChild的元素版

lastElementChild:指向最后一個子元素;lastChild的元素版

previousElementSibling:指向前一個同輩元素;previousSibling的元素版

nexrtElementSibling:指向后一個同輩元素;nextSibling的元素版

Browser Compatibility

DOM2級樣式 訪問元素的樣式 style對象
這個style對象是CSSStyleDeclaration的實例,包含著通過HTML的style特性指定的所有樣式信息,但不包含與外部樣式表經層疊而來的樣式。

cssText

length

item(index)

getPropertyValue(propertyName)

removeProperty(propertyName)

setProperty(propertyName, value, priority)

getPropertyCSSValue(propertyName)

getPropertyPriority

parentRule

NOTE:

"DOM2級樣式"規范規定樣式對象上的相應屬性名應該是cssFloat。而IE則支持的是styleFloat

對于使用短劃線(例如background-image)的CSS屬性名,必須將其轉換成駝峰大小寫形式,才能通過Javascript來訪問。

計算樣式
getComputeStyle():
接收兩個參數,第一個參數為,要取得計算樣式的元素和一個偽元素字符串。
返回一個CSSStyleDeclaration對象,其中包含當前元素的所有計算的樣式。
// IE
var myDiv = document.getElementById("myDiv");
var computeStyle = myDiv.style.currentStyle

// 其他瀏覽器
var computeStyle = document.defaultView.getComputedStyle(myDiv, null)

NOTE:無論在哪個瀏覽器,所有計算的樣式都是只讀的。

操作樣式表
CSSStyleSheet類型表示的是樣式表,包括通過元素的樣表和在

            <