1. 程式人生 > >《JavaScript Dom 編程藝術》讀書筆記-第7章

《JavaScript Dom 編程藝術》讀書筆記-第7章

write 瀏覽器中 requests elm event 數據 筆記 它的 自己

動態創建標記~內容包括:

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章