《JavaScript DOM 編程藝術 》 《JavaScript 高級程序設計》
平穩退化和漸進增強
在 JavaScript DOM 編程藝術一書中,個人認爲,最核心的思想是作者提到的平穩退化和漸進增強。
所謂的平穩退化,就是讓JS代碼適應所有的用戶,這是一個基礎,不管用戶處於什麼環境,都要爲用戶提供最基本的可訪問性。
而漸進增強則是爲高級用戶提供更好的體驗效果,利用JS去包裝原始的HTML數據,但前提是JS只是一個行爲層,必須與結構層分離。
也就是說在平穩退化的基礎上漸進增強,而漸進增強的結果一般都是符合平穩退化的。
DOM
JavaScript 主要由3部分組成,也就是 ECMAScript,DOM,BOM。
作爲 JavaScript 的重要組成部分,DOM 的全稱是 Document Object Model,即是文檔對象模型。用類似於家譜的樹形結構來表示 DOM 再適合不過了,而組成這個 DOM Tree 的就是節點。
節點——Node 類型
nodeType 屬性
DOM 中定義了12中 Node 類型,其中主要有3種節點:元素節點、文本節點、文檔節點。
元素節點的 nodeType 屬性值爲 Node.ELEMENT_NODE 或 1。
文本節點的 nodeType 屬性值爲 Node.TEXT_NODE 或 3。
文檔節點的 nodeType 屬性值爲 Node.DOCUMENT_NODE 或 9。
注:爲了跨瀏覽器,一般使用數值表示 nodeType 屬性。
nodeName 屬性和 nodeValue 屬性
childNodes 屬性
關於 NodeList 對象
function convert2Array(nodes){
var array = null;
try{
//針對非IE瀏覽器
array = Array.prototype.slice.call(nodes, 0);
}
//IE8-瀏覽器會捕獲錯誤
catch(e){
array = new Array();
for(var i = 0, len = nodes.length ; i < len ; i ++){
array.push(nodes[i]);
}
}
return array;
}
parentNode 屬性、previousSibling 屬性、nextSibling 屬性、firstChild 屬性、lastChild 屬性 和 hasChildNodes() 方法
appendChild() 方法、insertBefore() 方法、replaceChild() 方法 和 removeChild() 方法
/*
原有的 html 結構:
<div id="a">
<div id="b"></div>
</div>
*/
var a = document.getElementById("a");
//若已經創造了新的節點 c
var newNode = a.appendChild(c);
alert(newNode == c); //true
/*
此時 html 結構爲
<div id="a">
<div id="b"></div>
<div id="c"></div>
</div>
*/
//若新插入的節點已存在,appendChild 則會改變原來的位置爲當前位置
var newNode = a.insertBefore(d,b);
alert(newNode == d); //true
/*
此時 html 結構爲
<div id="a">
<div id="d"></div>
<div id="b"></div>
<div id="c"></div>
</div>
*/
var newNode = a.replace(e,d);
alert(newNode == e); //tue
/*
此時 html 結構爲
<div id="a">
<div id="e"></div>
<div id="b"></div>
<div id="c"></div>
</div>
*/
var removeNode = a.removeChild(e);
alert(removeNode == e);//true
/*
此時 html 結構爲
<div id="a">
<div id="b"></div>
<div id="c"></div>
</div>
*/
自定義 insertAfter() 方法
DOM 中沒有提供 insertAfter() 方法,但我們可以自己定義:function insertAfter(newNode, targetNode){
var parent = targetNode.parent;
if(parent.lastChild == targetNode){
parent.appendChild(newNode);
}
else{
parent.insertBefore(newNode, targetNode.previousSibling);
}
}
文檔節點——Document 類型
document 對象
查找元素:
getElementById() 方法:
注:按照平穩退化漸進增強的原則,使用前做出判斷,如
if(!document.getElementById){
return false;
}
var link = document.getElementById("a");
getElementsByTagName
var links = document.getElementsByTagName("a");
for(var i = 0 ; i < links.length ; i ++){
alert(links[i].title);
}
getElementsByClassName
HTML5 DOM 中新增的一個方法,按照元素的 class 值返回一個 HTMLCollection 對象,可查找帶有多個類名的元素,且類名順序不會有影響
var links = document.getElementsByClassName("link item");
alert(links.length);
元素節點——Element 類型
屬性操作
getAttribute
if(!document.getElementById){
return false;
}
var link = document.getElementById("item");
alert(link.getAttribute("src"));
link.getAttribute("src") 相當於 link.src,也就是直接採用 DOM 對象直接訪問。setAttribute
var links = document.getElementsByTagName("a");
for(var i = 0 ; i < links.length ; i ++){
links[i].setAttribute("title","title"+i);
}
links[i].setAttibute("title","title"+i) 相當於 links[i].title = "title" + i;
removeAttribute
移除屬性的值
var link = document.getElementById("item");
link.removeAttribute("title");
注:IE6- 不支持創建元素——document.ceateElement()
if(client.browser.ie && client.browser.ie <= 7){
var iframe = document.createElement("<iframe name=\"myframe\"></iframe>");
var input = document.createElement("<input type=\"checkbox\" />");
var button = document.createElement("<button type=\"reset\"></button>");
var radio1 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"1\" />");
var radio2 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"2\" />");
}
注:其他瀏覽器不支持此寫法,所以要檢測瀏覽器。文本節點——Text 類型
創建文本節點 document.createTextNode()
var p = document.getElementById("text");
var txt1 = document.createTextNode("hello ");
var txt2 = document.createTextNode("word!");
p.appendChild(txt1);
p.appendChild(txt2);
alert(p.childNodes.length); //2
p.normalize();
alert(p.childNodes.length); //1
文檔片段——DocumentFragment 類型
var fragment = document.createDocumentFragment();
var ul = document.getElementById("list");
var li = null;
for(var i = 0 ; i < 5 ; i ++){
li = document.createElement("li");
li.appendChild(document.createTextNode("item"+i));
fragment.appendChild(li);
}
ul.appendChild(fragment);
避免了 for 循環中一直爲 ul 添加子節點而造成頁面的反覆渲染。