本篇筆記是本書的第七阅嘶、八、九章內(nèi)容组民,前六章知識可查看JavaScript Dom編程藝術(shù)學習筆記1
- <a href="#c1">第七章 動態(tài)創(chuàng)建標記</a>
- <a href="#c2">第八章 充實文檔的內(nèi)容</a>
- <a href="#c22">第九章 CSS-DOM</a>
<a name="c1"></a>第七章 動態(tài)創(chuàng)建標記
本章內(nèi)容:
- 傳統(tǒng)技術(shù):document.write和innerHTML棒仍;
- 深入剖析DOM方法:createElement、createTextNode邪乍、appendChild和insetBefore降狠。
1.document.write和innerHTML
-
document.write
, 違背了“行為應(yīng)該與表現(xiàn)分離”原則,應(yīng)避免使用該方法 -
innerHTML
, 始于微軟IE4瀏覽器庇楞,可用來讀榜配、寫某給定元素里的HTML內(nèi)容。需要把一大段HTML內(nèi)容插入網(wǎng)頁時吕晌,innerHTML更適用 - 一旦使用了
innerHTML
屬性蛋褥,它的全部內(nèi)容將被替換掉
2.DOM方法
在DOM看來,一個文檔就是一棵節(jié)點樹睛驳。要在節(jié)點樹上添加內(nèi)容烙心,就必須插入新的節(jié)點;要添加一些標記到文檔乏沸,就必須插入元素節(jié)點淫茵。
-
createElement方法:
var para = document.createElement("p");
,此時的p元素還不是DOM節(jié)點樹的組成部分蹬跃,這種情況稱為文檔碎片(document fragment) -
appendChild方法:
把新節(jié)點加入節(jié)點樹匙瘪,parent.appendChild(child)
var testdiv = document.getElementById("testdiv");
testdiv.appendChild(para);```
- **createTextNode方法:**
var txt = document.createTextNode("Hello world");
para.appendChild(txt);```
-
以上例子思路順序如下:
- 創(chuàng)建一個p元素節(jié)點;
- 創(chuàng)建一個文本節(jié)點蝶缀;
- 把這個文本節(jié)點追加到第一步創(chuàng)建的p元素節(jié)點上丹喻;
- 把p元素節(jié)點追加到test.html文檔中的一個元素節(jié)點上
-
insertBefore()
parentElement.insertBefore(newElement,targetElement)
- 新元素:要插入的元素newElement
- 目標元素:targetElement
- 父元素:目標元素的父元素parentElement,targetElement的parentNode屬性值就是父元素
- 在DOM里翁都,元素節(jié)點的父元素必須是另一個元素節(jié)點碍论,屬性節(jié)點和文本節(jié)點的子節(jié)點不允許是元素節(jié)點
insertAfter()函數(shù)
DOM本身未提供inserAfter方法,我們可以構(gòu)造該函數(shù):
function insertAfter(newElement,targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement,targetElement.nextSibling);
}
}
//該函數(shù)構(gòu)造思路可參考本書該章節(jié)
//同第六章構(gòu)造的addLoadEvent()函數(shù)
<a name = "c2"></a> 第八章 充實文檔的內(nèi)容
1.兩項原則
漸進增強(progressive enhancement):總是從最核心的內(nèi)容開始柄慰,根據(jù)內(nèi)容使用標記實現(xiàn)良好的結(jié)構(gòu)鳍悠,然后逐步加強這些內(nèi)容。這些增強工作既可以是通過CSS改進呈現(xiàn)效果先煎,也可以是通過DOM添加各種行為贼涩。內(nèi)容應(yīng)該在剛開始編寫文檔時就要成為文檔的組成部分。
平穩(wěn)退化:漸進增強的實現(xiàn)必然支持平穩(wěn)退化薯蝎。缺乏必要的CSS和DOM支持的訪問者仍然可以訪問到核心內(nèi)容遥倦。
2.顯示“縮略語”列表
- for (variable in array)
把數(shù)組的下標(鍵)臨時賦值給變量。 - <abbr>和<acronym>
<abbr>:縮略語占锯,對單詞或短語的簡寫形式的統(tǒng)稱袒哥;
<acronym>:首字母縮寫詞
HTML5中,已統(tǒng)一使用<abbr>消略。 - 示例代碼:
通過注釋可了解到一些知識點和思路
function displayAbbreviations(){
if(!document.getElementsByTagName || !document.createElement || !document.createTextNode) retrun false;
//取得所有縮略詞
var abbreviations = document.getElementsByTagName("abbr");
if (abbreviations.length < 1) return false;
var defs = new Array();
//遍歷這些縮略詞
for(var i = 0; i<abbreviations.lentgh; i++){
var current_abbr = abbreviations[i];
//解決IE兼容問題
if(current_abbr.childNodes.lentgh < 1) continue;
//得到當前縮略語的解釋文字堡称,即title屬性的值
var definition =current_abbr.getAttribute("title");
//得到文本節(jié)點的nodeValue屬性并把它賦值給變量key,即縮略短語本身
var key = current_abbr.lastChild.nodeValue;
//把key用作數(shù)組元素的下標(鍵),definition用作數(shù)組元素的值
//比如defs數(shù)組第一個元素的下標是W3C艺演,值是World Wide Web Consortium
defs[key] = definition;
}
//創(chuàng)建定義列表
var dlist = document.createElement("dl");
//對于defs關(guān)聯(lián)數(shù)組里的每個鍵却紧,把它的值賦給變量key
for(key in defs){
var definition = defs[key];
//創(chuàng)建定義標題
var dtitle = document.createElement("dt");
var dtitle_text = document.createTextNode(key);
dtitle.appendChild(dtitle_text);
//create the definition description
var ddesc = document.createElement("dd");
var ddesc_text = document.createTextNode(definition);
ddesc.appenChild(ddesc_text);
dlist.appenChild(dtitle);
dlist.appenChild(ddesc);
}
//IE兼容性
if(dlist.childNodes.lentgh < 1) return false;
var header = document.createElement("h2");
var header_text = document.createTextNode("Abbreviations");
header.appenChild(header_text);
document.body.appendChild(header);
document.body.appendChild(dlist);
}
addLoadEvent(displayAbbreviations);
3.顯示“文獻來源連接表”
-
步驟:
- 遍歷這個文檔里所有的blockquote桐臊;
- 從blockquote元素提出去cite屬性的值;
- 創(chuàng)建一個標示文本是source的鏈接晓殊;
- 把這個鏈接賦值為blockquote元素的cite屬性的值断凶;
- 把這個鏈接插入到文獻節(jié)選的末尾
注意:
編寫DOM腳本時,一定要檢查nodeType屬性值巫俺。很多DOM方法只能用于元素節(jié)點认烁,如果用在文本節(jié)點上就會出錯。示例代碼:
一些思路和知識點可參考注釋
function displayCitations(){
if(!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
var quotes = getElementsByTagName("blockquote");
for(var i = 0; i < quotes.lentgh; i++){
//如果沒有cite屬性介汹,繼續(xù)循環(huán)
if(!quotes[i].getAttribute("cite")) continue;
var url = quotes[i].getAttribute("cite");
//變量url包含著將成為那個鏈接的href屬性值的字符串
var quoteChildren = quotes[i].getElementsByTagName("*");
//如果沒有元素節(jié)點却嗡,繼續(xù)循環(huán)
if(quoteChildren.length < 1) continue;
//取得引用中的最后一個元素節(jié)點
var elem = quoteCildren[quoteCildren.lentgh - 1];
//elem變量包含著將成為那個鏈接在文檔中的插入位置的節(jié)點
var link = document.createElement("a");
var link_text = document.createTextNode("source");
link.appendChild(link_text);
link.setAttribute("href", url);
var superscript = document.createElement("sup");
superscript.appenChild(link);
elem.appenChild(superscript);
}
}
4.顯示“快捷鍵清單”
accesskey
屬性可以把一個元素(如鏈接)與鍵盤某個特定的鍵關(guān)聯(lián)在一起
步驟和前兩小節(jié)類似,不再贅述嘹承,可參考這個書原文:)
關(guān)于基本鍵的約定俗成的設(shè)置可參考這里.
5.檢索和添加信息
- 對文檔現(xiàn)有信息進行檢索窗价,需要用到下列方法:
getElementById
getElementsByTagName
getAttribute - 把信息添加到文檔里,需要使用下列方法:
createElement
createTextNode
appendChild
insertBefore
setAttribute
<a name="c22"></a>第九章 CSS-DOM
1.三位一體的網(wǎng)頁
瀏覽器的網(wǎng)頁是由結(jié)構(gòu)層(HTML/XHTML)叹卷、表現(xiàn)層(CSS)和行為層(JS&DOM)構(gòu)成的共同體
2.style屬性
style屬性是一個對象舌镶,可用typeof驗證。
需要引用一個中間帶減號的CSS屬性時豪娜,DOM要求使用駝峰命名法:
font-family -> element.style.fontFamily
3.何時用DOM腳本設(shè)置樣式
3.1 根據(jù)元素在節(jié)點樹里的位置設(shè)置樣式
(1)通過CSS聲明樣式主要有三種:
- 為標簽元素統(tǒng)一聲明樣式:
p{font-size: 1em;}
- 為有特定class屬性的元素統(tǒng)一聲明樣式:
.fineprint{font-size: 0.8em;}
- 為有id屬性的元素單獨聲明樣式:
#intro{font-size: 1.2em;}
- 還可以根據(jù)元素的位置聲明樣式餐胀。
(2)構(gòu)造獲取“下一個元素節(jié)點”函數(shù)
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if (node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
3.2 根據(jù)某種條件反復設(shè)置某種樣式
JavaScript特別擅長處理重復性任務(wù),構(gòu)造一個函數(shù)為表格添加斑馬線效果瘤载,隔行設(shè)置就OK:
(1) 把文檔里的所有table元素找出否灾;
(2) 對每個table元素創(chuàng)建odd變量并初始化為false;
(3) 遍歷這個表格里的所有數(shù)據(jù)行
(4) 如果變量odd的值是true鸣奔,設(shè)置樣式并把odd變量修改為false墨技;
(5) 如果變量odd的值是false,不設(shè)置樣式挎狸,但把odd變量修改為true扣汪。
function stripeTables() {
if (!document.getElementsByTagName) return false;
var tables = document.getElementsByTagName("table");
for (var i=0; i<tables.length; i++) {
var odd = false;
var rows = tables[i].getElementsByTagName("tr");
for (var j=0; j<rows.length; j++) {
if (odd == true) {
rows[j].sytle.backgroundColor = "#fcc";
odd = false;
} else {
odd = true;
}
}
}
}
addLoadEvent(stripeTables);
3.3 響應(yīng)事件
采用純粹的CSS還是利用DOM來設(shè)置樣式,需要考慮下面兩點:
- 這個問題最簡單的解決方案是什么锨匆;
- 哪種解決方案會得到更多瀏覽器的支持崭别。
4.className屬性
與其使用DOM直接改變某個元素的樣式,不如通過JS代碼去更新這個元素的class屬性恐锣。
如果元素已經(jīng)有了class茅主,可把新的class設(shè)置值追加到className屬性上去(intro的第一個字符是空格):
elem.className += " intro"
需要給一個元素追加新的class時:
- 檢查className屬性的值是否為null
- 如果是,把新的class設(shè)置值直接賦值給className屬性土榴;
- 如果不是诀姚,把一個空格和新的class設(shè)置值追加到className屬性上。
function addClass(element,value) {
if (!element.className) {
element.className = value;
} else {
newClassName = element.className;
newClassName+= " ";
newClassName+= value;
element.className = newClassName;
}
}
//第一個參數(shù)是需要添加新class的元素(element)玷禽,第二個是新的class設(shè)置值(value)
5.對函數(shù)進行抽象
示例:
function styleHeaderSiblings() {
if (!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
for (var i=0; i<headers.length; i++) {
var elem = getNextElement(headers[i].nextSibling);
addClass(elem,"intro");
}
}
給改進后的函數(shù)styleElementSibling增加兩個函數(shù)tag和theclass赫段,參數(shù)變量tag和theclass代替原函數(shù)的字符串"h1"和"intro"呀打。
function styleHeaderSiblings(tag, theclass) {
if (!document.getElementsByTagName) return false;
var elems = document.getElementsByTagName("tag");
for (var i=0; i<headers.length; i++) {
var elem = getNextElement(headers[i].nextSibling);
addClass(elem, theclass);
}
}
addLoadEvent(function(){
styleElementSibling("h1", "intro");
})