《JavaScript Dom 編程藝術》讀書筆記-第7章
動態創建標記~內容包括:
1. 傳統技術:document.write 和innerHTML
2. 深入剖析DOM方法:createElemen、createTextNode、appendChild和innerBefore
核心在於JavaScript也可以用來改變網頁的結構和內容。
傳統方法:document.write。違背了行為應該與表現分離。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test</title></head> <body> <script>document.write("hello world")</script> </body> </html>
以插入的字符串為參數,將一個<p>,字符串和</p>標簽拼接到一起。
function insertParagraph(text){ var str="<p>"; str+=text; str+="</p>"; document.write(str); }
在HTML文檔中插入:
<script src="example.js"></script> <script>insertParagraph("hello world")</script>
想這樣把JS與HTML混雜起來很不好。只要有可能,就應該用外部CSS文件代替<font>標簽去設定和管理頁面的樣式,最好用外部JavaScript文件去控制網頁行為。應該避免在<body>部分亂用<script>標簽,避免使用document.write方法。
innerHTML
先如今的瀏覽器幾乎都支持innerHTML,這個屬性並不是W3C DOM標準的組成部分,但現在已經包含到HTML5規範中。
innerHTML屬性可以用來讀寫某個給定元素裏的HTML內容。
<div> <p>this is <em>my</em> content</p> </div>
window.onload=function(){ var testdiv=document.getElementById("testdiv"); alert(testdiv.innerHTML);//輸出<p>this is <em>my</em> content</p>
}
innerHTML屬性毫無細節可言。一旦使用innerHTML,它的全部內容都會被替換。
window.onload=function(){ var testdiv=document.getElementById("testdiv"); testdiv.innerHTML="<p>this is <em>my</em> content</p>"; }
要想獲得細節,就必須使用DOM方法和屬性。在任何時候,標準的DOM都可以用來代替innerHTML。
DOM方法
在DOM看來一個文檔就是一顆節點樹。如果你想在節點樹上添加內容,就必須插入新的節點。
<div id="testdiv"> </div>
createElement:
var para=document.createElment<"p">;
appendChild:
var testdiv=document.getElementById("testdiv"); testdiv.appendChild=para;
createTextNode
window.onload=function(){
var para=document.createElement("p");
var testdiv=document.getElementById("testdiv");
testdiv.appendChild(para);
var txt=document.createTextNode("hello world");
para.appendChild(txt);
}
一個更復雜的組合。現在想顯示如下內容:
<p>this is <em>my</em> content</p>
JS代碼如下:
window.onload=function(){ var para=document.createElement("p"); var testdiv=document.getElementById("testdiv"); testdiv.appendChild(para); var txt=document.createTextNode("this is"); para.appendChild(txt); var emph=document.createElement("em"); var txt2=document.createTextNode("my"); emph.appendChild(txt2); para.appendChild(emph); var txt3=document.createTextNode(" content"); para.appendChild(txt3);
}
重回圖片庫
圖片庫中的placeholder和描述是只為了圖片顯示而存在的,所以此處我們將用DOM來創建它們。
var placeholder=document.createElement("img");//創建圖像節點 placeholder.setAttribute("src",image/1.jpg); placeholder.setAttribute("id",placehold); placeholder.setAttribute("alt",my image gallery); var describe=document.createElement("p");//創建描述節點 describe.setAttribute("id",description); var txt=document.createTextNode("this is a description"); describe.appendChild(txt); document.getElementsByTagName("body")[0].appendChild(placeholder);//插入至BODY元素 document.getElementsByTagName("body")[0].appendChild(describe);
在已有元素前插入一個新元素:
parentElement.insertBefore(newElement,targetElement);
var gallery=document.getElementById("imagegallery");//等同於上面JS代碼的後兩行 gallery.parentNode.insertBefore(placeholder,gallery); gallery.parentNode.insertBefore(describe,gallery);
在已有元素後插入一個新元素:
DOM本身沒有提供insertAfter的方法,但可以自己寫一個。
function insertAfter(newElement,targetElement){ var parent=targetElement.parentNode; if (parent.lastChild==targetElement) { parent.appendChild(newElement); }else { parent.insertBefore(newElement,targetElement.nextSibling); } }
Ajax:異步加載網頁的技術。對頁面的請求以異步方式發送到服務器。服務器不會用整個頁面來響應請求,他會在後臺處理請求,與此同時用戶還能繼續瀏覽網頁並與頁面交互。JS腳本按需加載和創建網頁內容,而不會打斷用戶的瀏覽體驗。Ajax依賴於JavaScript。
技術的核心是XMLHttpRequest對象。(充當瀏覽器中的腳本【即客戶端】與服務器之間的中間人角色)。
例子:
HTML文檔
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Ajax</title> </head> <body> <div id="new"></div> <script src="addLoadEvent.js"></script> <script src="getHTTPObject.js"></script> <script src="getNewContent.js"></script> </body> </html>
三個JS文件:
function addLoadEvent(func){ var oldload=window.onload; //alert(typeof oldload) if (typeof oldload !=‘function‘) { window.onload=func;//為什麽此處window.onload不能換為oldload }else{ window.onload=function(){ oldload(); func(); } } }
function getHTTPObject(){ if (typeof XMLHttpRequest=="undefined") { XMLHttpRequest=function(){ try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0");} catch(e){} try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0");} catch(e){} try{ return new ActiveXObject("Msxml2.XMLHTTP");} catch(e){} return false; } } return new XMLHttpRequest(); }
function getNewContent(){ var request=getHTTPObject(); if (request) { request.open("GET","example.txt",true); request.onreadystatechange=function(){ if (request.readyState==4) { var para=document.createElement("p"); var txt=document.createTextNode(request.responseText); para.appendChild(txt); document.getElementById("new").appendChild(para); } }; request.send(null); }else{ alert("sorry~~~") } } addLoadEvent(getNewContent)
使用XMLHttpRequest對象發送的請求只能訪問與其所在的HTML處於同一個域中的數據,不能向其他域發送請求。有些瀏覽器會限制Ajax的協議。比如在chrome中,如果使用file://協議從之間的硬盤中加載example.txt文件,就會看到Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. 的錯誤消息。
異步請求容易被忽略的問題是異步性。腳本發送XMLHttpRequest請求之後,仍然會繼續執行,不會等待響應返回。
漸進增強與Ajax.
一開始基於老式的頁面刷新機制構建的,可以再既有框架的基礎上,用Ajax攔住發送到服務器的請求,並將請求交給XMLHttpRequest對象處理。
構建Ajax網站最好的方法,先構建一個常規的網站,然後Hijax(漸進增強的使用Ajax)它。
小結:
createElement
createTextNode
appendChild
insertBefore.
《JavaScript Dom 編程藝術》讀書筆記-第7章