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

資訊專欄INFORMATION COLUMN

《JavaScript高級程序設計》(第3版)讀書筆記 第10章 DOM

yearsj / 2541人閱讀

摘要:年月級規范成為的推薦標準,為基本的文檔結構及查詢提供了接口。這意味著中的對象與原生對象的行為或活動特點并不一致。結果第一條注釋就會成為中的第一個子節點。由于跨域安全限制,來自不同子域的頁面無法通過通信。

DOM(文檔對象模型)是針對HTML和XML文檔的一個API(應用程序編程接口)。DOM描繪了一個層次化的節點樹,允許開發人員添加、移除和修改頁面的某一部分。DOM脫胎于Netscape及微軟公司創始的DHTML(動態HTML),但現在它已經成為表現和操作頁面標記的真正跨平臺、語言中立方式。

1998年10月DOM 1 級規范成為W3C的推薦標準,為基本的文檔結構及查詢提供了接口。本章主要討論與瀏覽器中的HTML頁面相關的DOM1級的特性和應用,以及JavaScript對DOM1級的視線。

IE中的所有DOM對象都是以COM對象的形式實現的。這意味著IE中的DOM對象與原生JavaScript對象的行為或活動特點并不一致。本章將較多的談及這些差異。

節點層次

  
    Sample Page
  
  
    

Hello World!

可以將這個簡單的HTML文檔視為一個層次結構,如圖10-1所示。

文檔節點是每個文檔的根節點。在這個例子中,文檔節點只有一個子節點,既元素,我們稱之為文檔元素

文檔元素是文檔的最外層元素,文檔中的其他所有元素都包含在文檔元素中。每個文檔只能有一個文檔元素。在HTML頁面中,文檔元素始終都是元素。在XML中,沒有預定義的元素,因此任何元素都可能成為文檔元素。

Node 類型

DOM1級定義了一個 Node 接口,該接口將由 DOM 中所有節點類型實現。這個Node接口在JavaScript中是作為Node類型實現的;除了IE之外,在其他所有瀏覽器中都可以訪問到這個類型。

JavaScript中的所有節點類型都繼承自Node類型,因此所有節點類型都共享著相同的基本屬性和方法。

每個節點都有一個nodeType屬性,用于表明節點的類型。及誒單類型由在Node類型中定義的下列12個數值常量來表示,任何節點類型必居其一(編號為節點類型常量存儲的數值):

Node.ELEMENT_NODE

Node.ATTRIBUTE_NODE

Node.TEXT_NODE

Node.CDATA_SECTION_NODE

Node.ENTITY_REFERENCE_NODE

Node.ENTITY_NODE

Node.PROCESSING_INSTRUCTION_NODE

Node.COMMENT_NODE

Node.DOCUMENT_NODE

Node.DOCUMENT_TYPE_NODE

Node.DOCUMENT_FRAGMENT_NODE

Node.NOTATION_NODE

// 通過比較上面的常量,很容易的確定節點類型
// 在IE中無效
if (someNode.nodeType == Node.ELEMENT_NODE) {
  console.log("Node is an element");
}

// 由于IE沒有公開 Node 類型的構造函數
// 最好還是將 nodeType 屬性與數字比較
if (someNode.nodeType == 1) {
  console.log("Node is an element");
}

并不是所有節點類型都受到Web瀏覽器的支持。開發人員最常用的就是元素和文本節點。

nodeNamenodeValue 屬性

了解節點的具體信息,可以使用nodeNamenodeValue 兩個屬性。這兩個屬性的值完全取決于節點類型。在使用這兩個值以前,最好用上述的代碼檢查節點的類型。

if (someNode.nodeType == 1) {
  value = someNode.nodeName;            // nodeName的值是元素的標簽名
}
節點關系

每個節點都有一個childNodes屬性,其中保存著一個NodeList對象。注意,可以通過方括號語法來訪問NodeList的值,而且也有length屬性,但它并不是Array的實例

NodeList對象的獨特之處在于,它實際上是基于DOM結構動態執行查詢的結果,因此DOM結構的變化能夠自動反映在NodeList對象中。我們常說NodeList是有生命、有呼吸的對象,而不是我們第一次訪它的瞬間拍攝下來的一張快照。

// 方括號和 item() 語法結果是相同的
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = comeNode.childNodes.length;

// 雖然不是Array的實例,但我們可以將它轉換成數組
// 在IE8及之前的版本中無效
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0);
// 由于IE8及更早版本將 NodeList 實現為一個 COM 對象
// 必須手動枚舉所有成員,才能轉換成數組
function convertToArray(nodes) {
  var array = null;
  try {
    array = Array.prototype.slice.call(nodes, 0);      // 針對非IE瀏覽器
  } catch (ex) {
    array = new Array();
    for (var i=0, len=nodes.length; i < len; i++) {
      array.push(nodes[i]);
    }
  }

  return array;
}

每個節點都有一個parentNode屬性,指向文檔中的父節點。

包含在childNodes中的所有節點都具有相同的父節點,而相互之間是同胞節點。

通過每個節點的previousSiblingnextSibling 屬性可以訪問同一列表中的其他節點。列表第一個節點previousSiblingnull,列表最后一個nextSiblingnull,當然如果列表只有一個節點,那么兩個都是null

父節點的firstChildlastChild屬性分別指向第一個和最后一個。如果列表沒有節點,那么兩個屬性都是null

hasChildNodes()也是一個非常有用的方法,當查詢節點存在子節點時返回true,不存在返回false。這是比查詢childNodes.length更簡單的方法。

所有節點都有的最后一個屬性是ownerDocument,該屬性指向表示整個文檔的文檔節點。這種關系表示的是任何節點都屬于它所在的文檔,任何節點都不能同時存在兩個或更多個文檔中。通過這個屬性,我們可以不必在節點層次中通過層層回溯達到頂端,而是可以直接訪問文檔節點。

操作節點

因為關系指針都是只讀的,所以DOM提供了一些操作節點的方法 。

最常用的方法是appendChild(),用于向childNodes列表的末尾添加一個節點,執行后,方法返回新增的節點。

var returnedNode = someNode.appendChild(newNode);
console.log(returnedNode == newNode);           // true
console.log(someNode.lastChild ==newNode);      // true

如果需要把節點放在childNodes列表中某個特定的位置上,而不是放在末尾,可以使用insertBefore()方法。這個方法接收兩個參數:要插入的節點和作為參照的節點。插入節點后,被插入的節點會變成參照節點的前一個同胞節點(previousSibling),同時被方法返回。如果參照節點是null,則 insertBefore()appendChild() 執行相同操作。

// 插入后成為最后一個子節點
var returnedNode = someNode.insertBefore(newNode, null);

// 插入后成為第一個子節點
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);

// 插入后在最后一個子節點前面
var returnedNode = someNode.insertBefore(newNode, someNode.lastChild);

replaceChild() 替換節點。同樣接收兩個參數,插入的節點和參照節點。插入新的節點并將參照節點從文檔樹中移除,新的節點會從被替換的節點復制所有關系指針。盡管從技術上講,被替換的節點仍然在文檔中,但它在文檔中的位置已經不存在了。

removeChild() 移除節點。被移除的節點仍然在文檔中,但它在文檔中的位置已經不存在了。

以上四個方法必須先取得操作節點的父節點(代碼示例中是someNode)。在不存在子節點的節點上調用以上方法,會導致錯誤。

其他方法

還有兩個方法是所有節點都有的。

cloneNode() 用于創建調用這個方法的節點的一個完全相同的副本。接收一個布爾值參數,表示是否執行深復制。

傳入true。執行深復制,復制節點及其整個子節點樹

傳入false。執行淺復制,即只復制節點本身。

復制返回的節點副本屬于文檔所有,但并沒有為它制定父節點。因此這個節點副本就成為了一個“孤兒”,除非通過 appendChild() insertBefore() replaceChild() 將它添加到文檔中。

IE8及之前的版本不會為包含空白符的文字創建節點(TEXT)

clone() 方法不會復制添加到DOM節點中的JavaScript屬性,例如時間處理程序。這個方法只復制特性、(在明確指定的情況下也復制)子節點,其他一切都不會復制。

IE 會復制事件處理程序,所以我們建議在復制之前最好先移出事件處理程序。

  • item 1
  • item 2
  • item 3
var myList = document.getElementById("ul");
var deepList = myList.cloneNode(true);
// [text, li, text, li, text, li, text]
console.log(deepList.childNodes);
// 3 (IE < 9) 或 7 (其他瀏覽器)
// IE8及之前的版本不會為包含空白符的文字創建節點(TEXT)
console.log(deepList.childNodes.length);

var shallowList = myList.cloneNode(false);
console.log(shallowList.childNodes.length);     // 0

normalize() 方法唯一的作用就是處理文檔樹中的文本節點。由于解析器的實現或DOM操作等原因,可能會出現文本節點不包含文本,或者連接出現兩個節點的情況。當在某個節點上調用這個方法時,就會在該節點的后代節點中查找上述兩種情況。

如果找到了空文本節點,則刪除它

如果找到相鄰的文本節點,則將它們合并為一個文本節點

本章后面還將進一步討論方法

var html = document.documentElement;               // 取得對的引用
console.log(html == document.childNodes[0]);       // true
console.log(html == document.firstchild)           // true

所有瀏覽器都支持document.documentElementdocument.boyd 屬性

Document另一個可能的子節點是DocumentType。通常將標簽看成一個與文檔其他部分不同的實體,可以通過doctype屬性(在瀏覽器中是document.doctype)來訪問信息。

瀏覽器對document.doctype的支持差別很大,所以這個屬性的用途很有限:

IE8及之前版本,如果存在文檔類型聲明,會將其錯誤的解釋為一個注釋并把它當做Comment節點;而document.doctype的值始終為null

IE9+,如果存在文檔類型聲明,則將其作為文檔的第一個子節點;document.doctype是一個DocumentType節點,也可以通過document.firstChilddocument.childNodes[0]訪問同一個節點。

Safari, Chrome, Opera :如果存在文檔類型聲明,則將其解析,但不作為文檔的子節點。document.doctype是一個DocumentType節點,但該節點不會出現在document.childNodes中。

從技術上說,出現在元素外部的注釋應該是算是文檔的子節點。然而,不同的瀏覽器在是否解析這些注釋以及能否正確處理他們等方面,也存在很大差異。



  
  

看起來這個頁面應該有3個子節點:注釋、元素、注釋。從邏輯上講,我們會認為document.childNodes中應該包含與這3個節點對應的3項。但是實際上,瀏覽器存在以下差異:

IE8及之前版本、Safari3.1及更高版本、Opera和Chrome 只為第一條注釋創建節點,不為第二條注釋創建節點。結果第一條注釋就會成為document.childNodes中的第一個子節點。

IE9+,將會將兩條都創建節點。

Firefox 和 Safari3.1之前的版本會完全忽略這兩條注釋。

多數情況下,我們都用不著在document對象上調用appendChild() removeChild() replaceChild() 方法,因為文檔類型(如果存在的話)是只讀的,而且它只能有一個元素子節點(該節點通常早就已經存在了)。

文檔信息

作為HMLTDocument的一個實例,document對象還有一些標準的Document對象所沒有的屬性。

title 包含著</b>元素中的文本。通過這個屬性可以取得當前頁面的標題,也可以修改當前頁面的標題并反映在瀏覽器的標題欄中。修改<b>title</b>屬性的值會改變<b><title></b>元素。</p> <pre>// 取得文檔標題 var originalTitle = document.title; // 設置文檔標題 document.title = "New page title";</pre> <p> <p>下面三個屬性與網頁的請求有關,所有這些信息都存在于請求的HTTP頭部,只不過是通過這些屬性讓我們能夠在JavaScript中訪問它們而已:</p> <p> <b>URL</b>屬性中包含頁面完整的URL(地址欄中的URL)</p> <p> <b>domain</b>屬性中值包含頁面的域名</p> <p> <b>referrer</b>屬性中可能會包含空字符串</p> <p> <b>URL</b>與<b>domain</b>屬性是相互關聯的。例如<b>document.URL</b>等于"http://www.wrox.com/WileyCDA/",那么<b>document.domain</b>就等于"www.wrox.com"。</p> <p>3個屬性中只有<b>domain</b>可以設置,但有安全方面的限制。如果URL中包含一個子域名,例如"p2p.wrox.com",那么就只能講<b>domain</b>設置為"wrox.com"(URL中包含"www",如"www.wrox.com"時,也是如此)。</p> <p>當頁面中包含來自其他子域的框架或內嵌框架時,能夠設置<b>document.domain</b>就非常方便了。由于跨域安全限制,來自不同子域的頁面無法通過JavaScript通信。而通過將每個頁面的<b>document.domain</b>設置為相同的值,這些頁面就可以互相訪問對方包含的JavaScript對象了。</p> </p> <pre>// 取得完整的URL var url = document.URL; // 取得域名 var domain = document.domain; // 取得來源 頁面的URL var referrer = document.referrer;</pre> <p>瀏覽器對<b>domain</b>屬性還有一個限制,即如果域名一開始是“松散的”(loose),那么就不能將它再設置為“緊繃的”(tight)。</p> <pre>// 假設頁面來自于 p2p.wrox.com域 document.domain = "wrox.com"; // 松散的(成功) document.domain = "p2p.wrox.com"; // 緊繃的(出錯)</pre> <b>查找元素</b> <p> <p><b>getElementById()</b> 接收一個參數:要取得的元素的ID。找到相應的元素則返回該元素,否則返回<b>null</b>。</p> <p>IE8及較低版本不區分ID大小寫</p> <p>如果頁面多個元素的ID相同,只會返回第一個匹配的元素。</p> <p>IE7及更早的版本添加了一個怪癖:name特性與給定ID匹配的表單元素也會被該方法返回。</p> <pre><input type="text" name="myElement" value="Text field"> <div class="br7lldz" id="myElement">A div</div> <script> // IE7中調用會返回<input>元素 var el = document.getElementById("myElement"); </script></pre> </p> <p> <b>getElementsByTagName()</b> 接收一個參數:要取得的元素的標簽名,而返回的是包含零或多個元素的<b>NodeList</b>。可以使用方括號語法或<b>item()</b>方法來訪問對象中的項。</p> <p> <b>namedItem()</b> 使用這個方法可以通過元素的name特性取得集合中的項。或方括號語法能達到同樣的效果</p> <pre><img src="myimage.gif" name="myImage"> <script> var images = document.getElementsByTagName("img"); console.log(images.length); console.log(images[0].src); // 方括號傳入數值就調用 item() console.log(images.item(0).scr); var myImage = images.namedItem("myImage"); var myImage = images["myImage"]; // 方括號傳入字符串就調用namedItem() </script></pre> <p>要取得文檔中的所有元素,可以向<b>getElementsByTagName()</b>中傳入"*"。在JavaScript及CSS中,星號通常表示全部。</p> <p>雖然標準規定標簽名需要區分大小寫,但為了最大限度的與既有HTML頁面兼容,傳給<b>getElementsByTagName()</b>的標簽名是不需要區分大小寫的。但對于XML頁面而言(包括XHTML),<b>getElementsByTagName()</b>方法就會區分大小寫。</p> <p> <b>getElementByName()</b> 是只有HTMLDocument類型才有的方法,返回帶有給定name屬性的所有元素。最常使用的情況是取得單選按鈕;為了確保發送給瀏覽器的值正確無誤,所有單選按鈕必須具有相同的name特性</p> <pre><fieldset> <legend>Which color do you prefer?</legend> <ul> <li> <input type="radio" value="red" name="color" id="colorRed"> <label for="colorRed">Red</label> </li> <li> <input type="radio" value="green" name="color" id="colorGreen"> <label for="colorGreen">Green</label> </li> <li> <input type="radio" value="blue" name="color" id="colorBlue"> <label for="colorBlue">Blue</label> </li> </ul> </fieldset></pre> <p>上述例子使用<b>getElementsByName()</b>方法可以返回三個input元素。但是對于這里的單選按鈕來說<b>namedItem()</b>方法只會取得第一項(因為每一項的name特性都相同)。</p> <b>特殊集合</b> <p> <b>document.anchors</b> 包含文檔中所有帶name特性的<b><a></b>元素</p> <p> <b>document.applets</b> 包含文檔中所有的<b><form></b>元素,與<b>document.getElementsByTagName("form")</b>得到的結果相同</p> <p> <b>document.images</b> 包含文檔中所有的<b><img></b>元素,與<b>document.getElementsByTagName("img")</b>得到的結果相同</p> <p> <b>document.links</b> 包含文檔中所有帶 <b>href</b> 特性的<b><a></b>元素</p> <b>DOM一致性檢測</b> <p>由于DOM分為多個級別,也包含多個部分,因此檢測瀏覽器實現了DOM的哪些部分就十分必要。<b>document.implementation</b>屬性就是為此提供的,與瀏覽器對DOM的實現直接對應。</p> <p>DOM1級別只為<b>document.implementation</b>規定了一個方法,即<b>hasFeature()</b>。接收兩個參數:要檢測的DOM功能的名稱及版本號。如果支持返回true</p> <pre>var hasXmlDom = docuemnt.implementation.hasFeature("XML", "1.0");</pre> <p>下表列出了可以檢測的不同值得版本號</p> <table> <thead><tr> <th>功能</th> <th>版本號</th> <th>說明</th> </tr></thead> <tbody> <tr> <td>Core</td> <td>1.0、2.0、3.0</td> <td>基本的DOM,用于描述表現文檔的節點樹</td> </tr> <tr> <td>XML</td> <td>1.0、2.0、3.0</td> <td>Core的XML拓展,添加了對CDATA、處理指令及實體的支持</td> </tr> <tr> <td>HTML</td> <td>1.0、2.0</td> <td>XML的HTML拓展,添加了對HTML特有元素及實體的支持</td> </tr> <tr> <td>Views</td> <td>2.0</td> <td>基于某些樣式完成文檔的格式化</td> </tr> <tr> <td>StyleSheets</td> <td>2.0</td> <td>將樣式表關聯到文檔</td> </tr> <tr> <td>CSS</td> <td>2.0</td> <td>對層疊樣式表1級的支持</td> </tr> <tr> <td>CSS2</td> <td>2.0</td> <td>對層疊樣式表2級的支持</td> </tr> <tr> <td>Events</td> <td>2.0, 3.0</td> <td>常規的DOM事件</td> </tr> <tr> <td>UIEvents</td> <td>2.0, 3.0</td> <td>用戶界面事件</td> </tr> <tr> <td>MouseEvents</td> <td>2.0, 3.0</td> <td>由鼠標引發的事件(click、mouseover等)</td> </tr> <tr> <td>MutationEvents</td> <td>2.0, 3.0</td> <td>DOM樹變化時引發的事件</td> </tr> <tr> <td>HTMLEvents</td> <td>2.0</td> <td>HTML4.01事件</td> </tr> <tr> <td>Range</td> <td>2.0</td> <td>用于操作DOM樹種某個范圍的對象和方法</td> </tr> <tr> <td>Traversal</td> <td>2.0</td> <td>遍歷DOM樹的方法</td> </tr> <tr> <td>LS</td> <td>3.0</td> <td>文件與DOM樹之間的同步加載和保存</td> </tr> <tr> <td>LS-Asnyc</td> <td>3.0</td> <td>文件與DOM樹之間的異步加載和保存</td> </tr> <tr> <td>Validation</td> <td>3.0</td> <td>在確保有效的前提下修改DOM樹的方法</td> </tr> </tbody> </table> <p> <b>hasFeature()</b> 方法確實方便,但也有缺點。因為實現者可以自行決定是否與DOM規范的不同部分保持一致。事實上,想讓<b>hasFearture()</b>針對所有值都有返回true很容易,但返回true有時候也不意味著實現與規范一致。</p> <p>為此我們建議,在使用<b>hasFreatrue()</b>之外,還同時使用能力檢測。</p> <b>文檔寫入</b> <p> <b>write()</b>和<b>writeln()</b>方法都接收一個字符串參數,即要寫入到輸出流中的文本。<b>wirte()</b>會原樣寫入,而<b>writeln()</b>則會在字符串的末尾添加一個換行符(n)。在頁面加載的過程中,可以使用這兩個方法動態的加入內容。</p> <p>在包含JavaScript文件時,必須注意不能像下面的例子那樣直接包含字符串"</script>",因為這會導致該字符串被解釋為腳本塊的結束,后面的代碼將無法執行。使用轉義"</script>"可以避免這個問題。</p> <p> <b>open()</b>和<b>close()</b>分別用于打開和關閉網頁的輸出流。如果是在頁面加載期間使用<b>write()</b>或<b>writeln()</b>方法,則不需要用到這兩個方法。</p> <p>嚴格型XHTML文檔不支持文檔吸入。對于那些按照<b>application/xml+xhtml</b>內容類型提供的頁面,這兩個方法也同樣無效。</p> <b>Element類型</b> <p> <b>Element</b>類型用于表現XML或XHTML元素,提供了對元素標簽名、子節點及特性的訪問。</p> <p> <p><b>Element</b>類型具有以下特征:</p> <p> <b>nodeType</b>的值為1</p> <p> <b>nodeName</b>的值為元素的標簽名</p> <p> <b>nodeValue</b>的值為<b>null</b> </p> <p> <b>parentNode</b>的值可能為Dcoment或Element</p> <p>其子節點可能是 <b>Element</b>、 <b>Text</b> 、 <b>Comment</b> 、 <b>ProcessingInstruction</b>、 <b>CDATASection</b>、 <b>EntityReference</b> </p> </p> <p>訪問元素的標簽名,可以使用<b>nodeName</b>屬性,也可以是使用<b>tagName</b>屬性,這兩個屬性會返回相同的值。</p> <pre>var div = document.getElementById("myDiv"); console.log(div.tagName); // "DIV" console.log(div.nodeName); // "DIV" console.log(div.tagName == div.nodeName); // true</pre> <pre>if (element.tagName == "div") { // 不能這樣比較,很容易出錯 } if (element.tagName.toLowerCase() == "div") { // 推薦這樣做(適用于任何文檔) }</pre> <b>HTML元素</b> <p> <p>所有HTML元素都由<b>HTMLElement</b>類型表示。<b>HTMLElement</b>類型直接繼承自Elment并添加了一些屬性。每個HTML元素中都存在的下列標準特性:</p> <p> <b>id</b> 元素在文檔中的唯一標識符</p> <p> <b>title</b> 有關元素的附加說明信息,一般通過工具提示條顯示出來</p> <p> <b>lang</b> 元素內容的語言代碼,很少使用</p> <p> <b>dir</b> 語言的方向值為"ltr"(left-to-right 從左至右)或 "rtl"</p> <p> <b>className</b> 與元素的class特性對應,即為元素指定的CSS類。沒有將這個屬性命名為class是因為class是ECMAScript的保留字。</p> </p> <p>并不是對所有屬性的修改都會在頁面中直觀的表現出來。對id或lang的修改對用戶而言是透明不可見的。而對title的修改則只會在鼠標移動到這個元素之上時才會顯示出來。對dir的修改會在屬性重寫的那一刻,立即影響頁面中文本的左右對齊方式。修改className時,如果新類關聯了與此前不同的CSS樣式,就立即應用新的樣式。</p> <p>下面表格列出了所有HTML元素以及與之關聯的類型(以斜體印刷的元素表示不推薦使用了)。注意表中的這些類型在Opera、Safari、Chrome、Firefox中都可以通過JavaScript訪問,但在IE8之前的版本中,不能通過JavaScript訪問。</p> <p><script type="text/javascript">showImg("https://segmentfault.com/img/bVbsSmI?w=828&h=682");</script><br><script type="text/javascript">showImg("https://segmentfault.com/img/bVbsSmO?w=948&h=520");</script></p> <b>取得特性</b> <p>操作特性的DOM方法主要有三個,分別是<b>getAttribute()</b>、<b>setAttribute()</b>、 <b>removeAttribute()</b>。</p> <pre>var div = document.getElemntByid("myDiv"); console.log(div.getAttribute("id")); // "myDiv" console.log(div.getAttribute("class")); // "bd" console.log(div.getAttribute("title")); // "Body Text" console.log(div.getAttribute("lang")); // "en" console.log(div.getAttribute("dir")); // "ltr"</pre> <p>注意,傳遞給<b>getAttribute()</b>的特性名與實際的特性名相同。因此想要得到class特性值,應該傳入"class" 而不是"className",后者只在通過對象屬性訪問特性時才用。</p> <p>如果給定的特性不存在,<b>getAttribute()</b>返回<b>null</b>。</p> <p>也可以取得自定義特性,即標準HTML語言中沒有的特性的值。需要注意,特性的名稱不區分大小寫,即"ID" 和 "id" 代表的都是同一個特性。另外也要注意,根據HTML5規范,自定義特性應該加上data-前綴以便驗證。</p> <p>任何元素的所有特性,也都可以通過DOM元素本身的屬性來訪問。當然<b>HTMLElement</b>也會有5個屬性與相應的特性一一對應。不過只有公認的(非自定義)特性才會以屬性的形式添加到DOM對象中。例如可以通過<b>div.id</b>訪問div元素的id屬性。不過自定義特性在Safari、Opera、Chrome、Firefox中是不存在的,但IE卻會為自定義特性也創建屬性。</p> <p>CSS通過<b>getAttribute()</b>訪問時,返回的style特性值中包含的是CSS文本,而通過屬性來訪問它則會返回一個對象。由于style屬性是用于以編程方式訪問元素樣式的(本章后面討論),因此并沒有直接映射到style特性。</p> <p>時間處理程序(例如onclick)通過<b>getAttribute()</b>訪問,返回的是相應的代碼字符串。而在訪問onclick屬性時,則返回的是一個JavaScript函數(如果未在元素中指定相應特性,則返回<b>null</b>)。這是因為onclick及其他事件程序屬性本身就應該被賦予函數值。</p> <p>由于存在上述差別,在通過JavaScript以編程方式操作DOM時,開發人員不經常使用 <b>getAttribute()</b>方法,而只是使用對象的屬性。只有在取得自定義特性值得情況下,才會使用<b>getAttribute()</b>方法。</p> <p>在IE7及以前版本中,通過<b>getAttribute()</b>訪問style特性或onclick,返回的值與屬性相同,都返回對象值或函數值。雖然IE8已經修復了這個bug,但不同IE版本間的不一致性,也是導致開發人員不適用<b>getAttribute()</b>訪問HTML特性的一個原因。</p> <b>設置特性</b> <p>與<b>getAttribute()</b>對應的方法時<b>setAttribute()</b>這個方法接收兩個參數:要設置的特性名和值。如果特性已經存在,<b>setAttribute()</b>會以指定的值替換現有的值;如果特性不存在,則創建該屬性并設置相應的值。</p> <p> <b>setAttribute()</b>方法既可以操作HTML特性也可以操作自定義特性。通過這個方法設置的特性名會統一轉換為小寫形式,即"ID"最終變成"id"。</p> <pre>div.setAttribute("id", "someOtherId"); div.id = "someOtherId"; // 添加自定義屬性,該屬性不會自動成為元素的特性 div.mycolor = "red"; div.getAttribute("mycolor"); // null ie除外</pre> <p> <b>removeAttribute()</b> 用于徹底刪除元素的特性,調用這個方法不僅會清楚特性的值,而且也會從元素中完全刪除特性。這個方法并不常用,IE6及以前版本不支持。</p> <pre>div.removeAttribute("class");</pre> <b>attributes屬性</b> <p>Element 類型是使用 attributes 屬性的唯一一個DOM節點類型 。</p> <p>attributes屬性中包含一個<b>NamedNodeMap</b>,與<b>NodeList</b>類似,也是一個動態集合。元素的每一個 特性都由一個<b>Attr</b>節點表示,每個節點都保存在<b>NamedNodeMap</b>對象中。</p> <p> <p><b>NamedNodeMap</b>對象擁有以下方法</p> <p> <b>getNamedItem(name)</b>:返回<b>nodeName</b>屬性等于<b>name</b>的節點</p> <p> <b>removeNamedItem(name)</b>:從列表中移除<b>nodeName</b>屬性 等于name的節點</p> <p> <b>setNameItem(node)</b>:向列表中添加節點,以節點的<b>nodeName</b>屬性為索引</p> <p> <b>item(pos)</b>:返回位于數字pos位置處的節點</p> </p> <p> <b>attributes</b>屬性中包含一系列節點,每個節點的<b>nodeName</b>就是特性的名稱,而節點的<b>nodeValue</b>就是特性的值。</p> <pre>// 取得元素的id var id = element.attributes.getNamedItem("id").nodeValue; // 設置元素的id element.attributes["id"].nodeValue = "someOtherId"; // 刪除元素id,并返回被刪除特性的Attr節點 var oldAttr = element.attributes.removeNamedItem("id"); // 傳入一個新的特性節點 element.attributes.setNameItem(newAttr);</pre> <p>由于attributes的方法不夠方便,因此開啊人員更多的會使用<b>getAttribute()</b>、<b>removeAttribute()</b>、<b>setAttribute()</b>方法。如果想要遍歷元素特性,可以用attributes</p> <p>針對attributes對象中的特性,不同瀏覽器返回的順序不同。</p> <p>IE7及更早版本返回HTML元素中所有可能的特性,包括沒有指定的特性。返回100多個特性是常見的</p> <pre>// 迭代元素的每一個特性,然后構造成 name="value"字符串 function outputAttributes(element) { var pairs = new Array(), attrName, attrValue, i, len; for (i=0, len=elment.attributes.length; i < len; i++) { attrName = element.attributes[i].nodeName; attrValue = element.attributes[i].nodeValue; // 針對 IE7- 做兼容 // 根據specified屬性,只返回指定的特性 if (element.attributes[i].specified) { paris.push(attrName + "="" + attrValue + """); } } return pairs.join(" "); }</pre> <b>創建元素</b> <p> <b>document.createElement()</b>方法可以創建新元素。只接收一個參數,即要創建元素的標簽名,在HTML文檔中不區分大小寫,而在XML(包括XHTML)文檔中,則是區分大小寫。</p> <p> <b>document.createElement()</b>創建元素的同時,也為新元素設置了<b>ownerDcoument</b>屬性。此時還可以操作元素的特性,為它添加更多子節點。</p> <p>由于新元素尚未被添加到文檔樹中,因此設置這些特性不會影響瀏覽器的顯示。要把新元素添加到文檔樹,可以使用<b>appendChild()</b> <b>insertBefore()</b> <b>replaceChild()</b>方法。</p> <pre>// 創建 var div = document.createElement("div"); // 操作元素特性,添加子節點 div.id = "myNewDiv"; div.className = "box"; document.body.appendChild(div);</pre> <p> <p>在IE中可以傳入完整的元素標簽,也可以包含屬性(僅IE支持)。這樣有助于避開在IE7及更早版本中動態創建元素的某些問題:</p> <p>不能設置動態創建的<b><iframe></b>元素的<b>name</b>特性</p> <p>不能通過表單的<b>reset()</b>方法重設動態創建的<b><input></b>元素(第13章討論reset()方法)</p> <p>動態創建的<b>type</b>特性值為“reset”的<b><button></b>元素重設不了表單</p> <p>動態創建的一批<b>name</b>相同的單選按鈕彼此毫無關系。</p> </p> <pre>if (client.browser.id && client.browser.ie <= 7) { var div = document.createElement("<div class="rtrtn57" id="myNewDiv" class="box"></div>"); }</pre> <b>元素的子節點</b> <p>元素可以有任意書目的子節點和后臺節點,因為元素可以是其他元素的子節點。元素的<b>childNodes</b>屬性中包含了它所有子節點,這些子節點可能是元素、文本節點、注釋或處理指令。不用瀏覽器在看待這些節點方面存在顯著的不同。</p> <pre><ul id="myList"> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul></pre> <p>IE解析,<b><ul></b>元素會有3個子節點,分別是3個<b><li></b>元素。但如果是其他瀏覽器,<b><ul></b>元素都會有7個元素,包括3個<b><li></b>元素和4個文本節點(表示<b><li></b>元素之間的空白符)。</p> <p>如果將元素間的空白符刪除,那么所有瀏覽器都會返回相同數目的子節點</p> <pre><ul id="myList"><li>item 1</li><li>item 2</li><li>item 3</li></ul></pre> <p>如果需要通過<b>childNodes</b>屬性遍歷子節點,那么一定不要忘記瀏覽器間的這一差別。這意味著在執行某項操作以前,通常都要先檢查<b>nodeType</b>屬性</p> <pre>for (var i=0, len = element.childNodes.length; i < len; i++) { if (element.childNodes[i].nodeTpe == 1) { ... } }</pre> <p>如果想通過某個特性的標簽名取得子節點或后代節點,可以通過元素調用<b>getElementsByTagName()</b>方法,結果只會返回當前元素的后代。</p> <pre>var ul = document.getElementById("myList"); var items = ul.getElementsByTagName("li");</pre> <b>Text類型</b> <p>文本節點由Text類型表示,包含的是可以照字面量解釋的純文本內容。純文本中可以包含轉義后的HTML字符,但不能包含HTML代碼。</p> <p> <p>Text節點具有以下特征:</p> <p> <b>nodeType</b>的值為3</p> <p> <b>nodeName</b>的值為"#text"</p> <p> <b>nodeValue</b>的值為節點所包含的文本</p> <p> <b>parentNode</b>是一個Element</p> <p>不支持(沒有)子節點</p> </p> <p>可以通過<b>nodeValue</b>屬性或<b>data</b>屬性訪問Text節點中包含的文本,這兩個屬性的值相同。對<b>nodeValue</b>的修改也會通過<b>data</b>反映出來,反之亦然。</p> <p> <p>使用下列方法可以操作節點中的文本</p> <p> <b>appendData(text)</b>:將text添加到節點的末尾</p> <p> <b>deleteData(offset, count)</b>:從offset指定的位置插入text</p> <p> <b>insertData(offset, text)</b>:在offset指定的位置插入text</p> <p> <b>replaceData(offset, count, text)</b>:用text替換從offset指定的位置開始到 offset+count為止處的文本</p> <p> <b>splitText(offset)</b>:從offset指定的位置將當前文本節點分成兩個文本節點。</p> <p> <b>substringData(offset, count)</b>:提取從offset指定的位置開始到 offset+count為止處的字符串</p> <p> <b>length</b>屬性:保存著節點中字符的書目。而且<b>nodeValue.length</b>和<b>data.length</b>中也保存著同樣的數值</p> </p> <p>在默認情況下,每個可以包含內容的元素最多只能有一個文本節點,而且必須確實有內容存在</p> <pre><!-- 沒有內容,也就沒有文本節點 --> <div></div> <!-- 有空格,因為有一個文本節點 --> <div> </div> <!-- 有內容,因為有一個文本節點 --> <div>Hello World!</div></pre> <pre>// 可以像這樣取得文本子節點 var textNode= div.firstChild; // 或者 div.childNodes[0] // 取得文本節點的引用后,就可以修改它了 div.firstChild.nodeValue = "Some other message";</pre> <p>如果這個文本節點當前存在于文檔樹中,那么修改文本節點的結果就會立即得到反映。</p> <p>修改文本節點時,字符串會經過HTML(或XML,取決于文檔類型)編碼。換言之,小于號、大于號或引號都會像下面的例子一樣被轉義</p> <pre>div.firstChild.nodeValue = "Some <strong>other</strong> message"; // 輸出結果:"Some <strong>other</strong> message"</pre> <p>這是在向DOM文檔中插入文本之前,先對其進行HTML編碼的一種有效方式</p> <b>創建文本節點</b> <p> <b>document.createTextNode()</b>創建新的文本節點。與設置已有文本節點的值一樣,作為參數的文本也將按照HTML或XML的格式進行編碼。</p> <pre>var textNode = document.createTextNode("<strong>Hello</strong> World!");</pre> <p>在創建新文本節點的同時,也會為其設置<b>ownerDocument</b>屬性。不過除非把新節點添加到文檔樹中已經存在的節點中,否則我們不會在瀏覽器窗口中看到新節點。</p> <pre>var element = document.createElement("div"); elment.className = "message"; var textNode = document.createTextNode("Hello world!"); element.appendChild(textNode); document.body.appendChild(element);</pre> <p>一般情況下,每個元素只有一個文本子節點。不過在某些情況下也可能包含多個文字子節點。相鄰的同胞文本節點,之間會連起來,中間不會有空格。</p> <pre>var element = document.createElement("div"); elment.className = "message"; var textNode = document.createTextNode("Hello world!"); element.appendChild(textNode); var anotherTextNode = document.createTextNode("Yippee!"); element.appendChild(anotherTextNode); document.body.appendChild(element);</pre> <b>規范化文本節點</b> <p>DOM文檔中存在相鄰的同胞文本節點很容易導致混亂,因為分不清文本節點之間的界限。于是催生了一個能夠將相鄰文本節點合并的方法。</p> <p> <b>normalize()</b>方法是由<b>Node</b>類型定義的(因而在所有節點類型中都存在)。如果在一個包含多個文本節點的父元素上調用<b>normalize()</b>方法,則會將所有文本節點合并成一個文本節點。</p> <pre>var element = document.createElement("div"); elment.className = "message"; var textNode = document.createTextNode("Hello world!"); element.appendChild(textNode); var anotherTextNode = document.createTextNode("Yippee!"); element.appendChild(anotherTextNode); document.body.appendChild(element); console.log(element.childNodes.length); // 2 element.normalize(); console.log(element.childNodes.length); // 1 console.log(element.firstChild.nodeValue); // "Hello World!Yippee!"</pre> <p>瀏覽器在解析文檔時永遠不會創建相鄰的文本節點,這種情況只會作為DOM操作的結果出現。</p> <p> <b>normalize()</b>有時候會導致IE6崩潰,IE7以上修復了此問題。</p> <b>分割文本節點</b> <p> <b>splitText()</b>方法會將一個文本節點分割成兩個。</p> <pre>var element = document.createElement("div"); elment.className = "message"; var textNode = document.createTextNode("Hello world!"); element.appendChild(textNode); document.body.appendChild(element); var newNode = element.firstChild.splitText(5); console.log(element.firstChild.nodeValue); // "Hello" console.log(newNode.nodeValue); // " World!" console.log(element.childNodes.length); // 2</pre> <b>Comment類型</b> <p> <p>注釋在DOM中是通過Comment類型來表示的。<b>Comment</b>節點具有以下特征:</p> <p> <b>nodeType</b>的值為8</p> <p> <b>nodeName</b>的值為 "#comment"</p> <p> <b>nodeValue</b>的值是注釋的內容</p> <p> <b>parentNode</b>可能是Dcoment或Element</p> <p>不支持(沒有)子節點</p> </p> <p>Comment類型與Text類型繼承自相同的基類,因此它擁有除<b>splitText()</b>之外的所有字符串操作方法。</p> <pre><div class="lp7rzxb" id="myDiv"><!--A comment--></div></pre> <pre>var div = document.getElementById("myDiv"); var comment = div.firstChild; console.log(comment.data); // "A comment"</pre> <p>使用<b>document.createComment()</b>并為其傳遞注釋文本也可以創建注釋節點</p> <pre>var comment = document.createComment("A comment ");</pre> <p>開發人員很少會創建和訪問注釋節點,此外瀏覽器也不會識別位于<b></html></b>標簽后的注釋。如果要訪問注釋節點,一定要保證它們是位于<b><html></b>和<b></html></b>之間。</p> <b>CDATASection類型</b> <p>CDATASection類型只針對基于XML的文檔,表示的是CDATA區域。與Comment類似、CDATASection類型繼承自Text類型,因此擁有除<b>splitText()</b>之外的所有字符串操作方法。</p> <p> <p>CDATASection節點具有下列特征:</p> <p> <b>nodeType</b>的值為4</p> <p> <b>nodeName</b>的值為"#cdata-section"</p> <p> <b>nodeValue</b>的值是CDATA區域中的內容</p> <p> <b>parentNode</b>可能是<b>Document</b>或<b>Element</b> </p> <p>不支持(沒有)子節點</p> </p> <p>CDATA區域只會出現在XML文檔中,因此多數瀏覽器都會把CDATA區域錯誤的解析為Comment或Element。</p> <pre><div class="9pzzlzf" id="myDiv"><![CDATA[This is some content.]]></div></pre> <p>這個例子中div元素應該包含一個CDATASection節點。但四大主流瀏覽器都不能正確解析。即使對于有效的XHTML頁面,瀏覽器也沒有正確的支持嵌入的CDATA區域。</p> <p>在真正的XML文檔中,可以使用<b>document.createCDataSection()</b>來創建CDATA區域。</p> <b>DocumentType類型</b> <p> <p>DocumentType類型在Web瀏覽器中并不常用,僅有 Firefox Safari 和 Opera支持它。</p> <p> <b>nodeType</b>的值為10</p> <p> <b>nodeName</b>的值為doctype的名稱</p> <p> <b>nodeValue</b>的值是<b>null</b> </p> <p> <b>parentNode</b>是<b>Document</b> </p> <p>不支持(沒有)子節點</p> </p> <p>通常,瀏覽器中的文檔使用的都是HTML或XHTML文檔類型,只有name屬性是有用的。</p> <pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"></pre> <pre>console.log(document.doctype.name); // "HTML"</pre> <p>IE不支持DocumentType,因此 <b>document.doctype</b>的值始終都是<b>null</b> </p> <b>DocumentFragment 類型</b> <p>所有節點類型中,只有DocumentFragment在文檔中沒有對應的標記。</p> <p> <p>DOM規定文檔片段(document fragment)是一種輕量級的文檔,可以包含和控制節點,但不會像完整的文檔那樣占用額外的資源。</p> <p> <b>nodeType</b>的值為11</p> <p> <b>nodeName</b>的值為"#document-fragment"</p> <p> <b>nodeValue</b>的值是<b>null</b> </p> <p> <b>parentNode</b>是<b>null</b> </p> <p>子節點可以是<b>Element</b> 、<b>ProcessingInstruction</b> 、<b>Comment</b> 、<b>Text</b>、 <b>CDATASection</b> 、<b>EntityReference</b> </p> </p> <p>雖然不能把文檔文段直接添加到文檔中,但可以將它作為一個倉庫來使用,在里面保存將來可能會添加到文檔中的節點。</p> <p> <b>document.createDocumentFragment()</b> 方法創建文檔片段</p> <pre><ul id="myList"></ul></pre> <pre>var fragment = document.createDocumentFragment(); var ul = document.getElementById("myList"); var li = null; // 如果直接向ul添加li元素會導致瀏覽器反復渲染 // fragment作為一個元素中轉的倉庫避免了這個問題 for (var i=0; i < 3; i++) { li = document.createElement("li"); li.appendChild(document.createTextNode("Item " + (i+1))); fragment.appendChild(li); } // 這里只會將fragment的所有子節點添加到ul上 // 而fragment本身永遠不會成為文檔樹的一部分 ul.appendChild(fragment);</pre> <b>Attr類型</b> <p> <p>元素的特性在DOM中以Attr類型來表示。在所有瀏覽器中(包括IE8),都可以訪問 Attr類型的構造函數和原型。</p> <p> <b>nodeType</b>的值為2</p> <p> <b>nodeName</b>的值就是特性的名稱</p> <p> <b>nodeValue</b>的值就是特性的值</p> <p> <b>parentNode</b>是<b>null</b> </p> <p>HTML中不支持(沒有)子節點</p> <p>XML中子節點可以是Text或EntityReference</p> </p> <p>盡管Attr是節點,但特性卻不被認為是DOM文檔樹的一部分。</p> <p>Attr對象有三個屬性:<b>name</b> <b>value</b> <b>specified</b>。</p> <p> <b>document.createAttribute()</b>傳入特性的名稱可以創建新的特性節點。</p> <pre>var attr = document.createAttribute("align"); attr.value = "left"; element.setAttribute(attr); console.log(element.attributes["align"].value); // left console.log(element.getAttributeNode("align").value); // left console.log(element.getAttribute("align")); // left</pre> <b>DOM操作技術</b> <b>動態腳本</b> <p>使用<b><script></b>元素可以向頁面中插入JavaScript代碼,一種是通過其src特性包含外部文件,另一種就是用這個元素本身包含代碼。</p> <p>動態加載的JavaScript文件能夠立即運行。</p> <pre>// 在執行最后一行代碼把<script>元素添加到頁面中之前 // 是不會下載外部文件的 var script = document.createElement("script"); script.type = "text/javascript"; script.src = "client.js"; document.body.appendChild(script);</pre> <pre><script type="text/javascript" src="client.js"></script></pre> <p>遺憾的是,并沒有什么標準方式來探知腳本是否加載完成。</p> <p>從邏輯上講,使用行內方式直接插入代碼是有效的。在Firefox Safari Chrome Opera中,都可以正常運行,但在IE中,會導致錯誤。IE將<b><script></b>視為一個特殊元素,不允許DOM訪問其子節點。不過可以使用<b><script></b>元素的text屬性來制定JavaScript代碼</p> <pre>var script = document.createElement("script"); script.type = "text/javascript"; // 這樣IE不支持 script.appendChild( document.createTextNode("function sayHi() { console.log("Hi")}") ); // 可以使用`<script>`元素的text屬性來制定JavaScript代碼 script.text = "function sayHi() { console.log("Hi")}"; document.body.appendChild(script);</pre> <p>Safari3之前的版本不支持這種寫法,可以這樣做兼容處理</p> <pre>var script = document.createElement("script"); script.type = "text/javascript"; var code = "function sayHi() { console.log("Hi")}" try { script.appendChild(document.createTextNode(code)); } catch (ex) { script.text = code; } document.body.appendChild(script);</pre> <p>實際上,這樣執行代碼與在全局作用域中把相同的字符串傳遞給<b>eval()</b>是一樣的。</p> <b>動態樣式</b> <p>與動態腳本類似,所謂動態樣式是指在頁面剛加載時不存在的樣式;動態樣式是在頁面加載完成后動態添加到頁面中的。</p> <pre>var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.href = "style.css"; var head = document.getElementsByTagName("head")[0]; head.appendChild(head);</pre> <pre><link rel="stylesheet" type="text/css" href="styles.css"></pre> <p>必須將<b><link></b>元素添加到<b><head></b>而不是<b><body></b>元素,才能保證所在瀏覽器中的行為一致。</p> <p>加載外部樣式文件的過程是異步的,也就是加載樣式 與執行JavaScript代碼的過程沒有固定的次序。</p> <p>一般是否知道樣式已加載完成并不重要,但也存在幾種利用事件來檢測這個過程是否完成的技術,將在第13章討論。</p> <p>行內方式插入樣式也是可以的,同樣要對IE做兼容處理</p> <pre>function loadStyleString(css) { var style = document.createElement("style"); style.type = "text/css"; try { style.appendChild(document.createTextNode(css)); } catch (ex) { style.styleSheet.cssText = css; } document.getElementsByTagName("head")[0].appendChild(style); }</pre> <p>如果專門針對IE編寫代碼,務必小心使用<b>styleSheet.cssText</b>屬性。在重用同一個<b><style></b>元素并再次設置這個屬性時,有可能導致瀏覽器崩潰。同樣將<b>cssText</b>屬性設置為空字符串也可能導致瀏覽器崩潰。</p> <b>操作表格</b> <p> <b><table></b>元素是HTML中最復雜的結構之一。想要創建表格,一般都必須涉及表示表格行、單元格、表頭等方面。由于涉及的標簽多,因而使用核心DOM方法創建和修改表格往往都免不了要編寫大量的代碼。</p> <pre><table border="1" width="100%"> <tbody> <tr> <td>Cell 1,1</td> <td>Cell 2,1</td> </tr> <tr> <td>Cell 1,2</td> <td>Cell 2,2</td> </tr> </tbody> </table></pre> <pre>// 使用核心DOM方法創建這些元素 // 創建table var table = document.createElement("table"); table.border = 1; table.width = "100%"; // 創建tbody var tbody = document.createElement("tbody"); table.appendChild(tbody); // 創建第一行 var row1 = document.createElement("tr"); tbody.appendChild(row1); var cell1_1 = document.createElement("td"); cell1_1.appendChild(document.createTextNode("Cell 1,1")); row1.appendChild(cell1_1); var cell2_1 = document.createElement("td"); cell2_1.appendChild(document.createTextNode("Cell 2,1")); row1.appendChild(cell2_1); // 創建第二行 var row2 = document.createElement("tr"); tbody.appendChild(row2); var cell1_2 = document.createElement("td"); cell1_2.appendChild(document.createTextNode("Cell 1,2")); row2.appendChild(cell1_2); var cell2_2 = document.createElement("td"); cell2_2.appendChild(document.createTextNode("Cell 2,2")); row2.appendChild(cell2_2); // 將表格添加到文檔主體中 document.body.appendChild(table);</pre> <p>DOM代碼很長,還有點不好理解。為了方便構建表格,HTMLDOM還為<b><table></b> <b><tbody></b> <b><tr></b> 元素添加了一些屬性和方法。</p> <p> <p><b><table></b>元素添加的屬性和方法:</p> <p>caption: 保存著對<b><caption></b>元素(如果有)的指針</p> <p>tBodies: 是一個<b><tbody></b>元素的HTMLCollction</p> <p>tFoot: 保存著對<b><tfoot></b>元素的(如果有)指針</p> <p>tHead: 保存著對<b><thead></b>元素的(如果有)指針</p> <p>rows: 是一個表格中所有行的HTMLCollection</p> <p>createTHead(): 創建<b><thead></b>元素,將其放到表格中,返回引用</p> <p>createTFoot(): 創建<b><tfoot></b>元素,將其放到表格中,返回引用</p> <p>createCaption(): 創建<b><caption></b>元素,將其放到表格中,返回引用</p> <p>deleteTHead(): 刪除<b><thead></b>元素</p> <p>deleteTFoot(): 刪除<b><tfoot></b>元素</p> <p>deleteCaption(): 刪除<b><caption></b>元素</p> <p>deleteRow(pos): 刪除指定位置的行</p> <p>insertRow(pos): 向<b>rows</b>集合中的指定位置插入一行</p> </p> <p> <p>為<b><tbody></b>元素添加的屬性和方法如下:</p> <p>rows: 保存著<b><tbody></b>元素中行的HTMLCollection</p> <p>deleteRow(pos): 刪除指定位置的行</p> <p>insertRow(pos): 向<b>rows</b>集合中的指定位置插入一行</p> </p> <p> <p>為<b><tr></b>元素添加的屬性和方法如下:</p> <p>cells: 保存著<b><tr></b>元素中單元格的HTMLCollection</p> <p>deleteCell(pos): 刪除指定位置的單元格</p> <p>insertCell(pos): 向<b>cells</b>集合中的指定位置插入一個單元格,返回對新插入單元格的引用。</p> </p> <pre>// 根據以上屬性和方法,可以大大簡化前述代碼 // 創建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(0); 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,2")); // 將表格添加到文檔主體中 document.body.appendChild(table);</pre> <b>使用NodeList</b> <p>理解 <b>NodeList</b> 及其近親 <b>NamedNodeMap</b> 和 <b>HTMLCollection</b>,是從整體上透徹理解DOM的關鍵所在。這三個集合都是動態的,每當文檔結構發生變化,它們都會得到更新。</p> <p>本質上說,所有<b>NodeList</b>對象都是在訪問DOM文檔實時運行的查詢。</p> <pre>// 下列代碼會導致無限循環 var divs = document.getElementsByTagName("div"); var div; // 每次循環都要對條件 i < divs.length 求值 // 但每次循環都添加了一個新的div for (var i=0; i < divs.length; i++) { div = document.createElement("div"); document.body.appendChild(div); }</pre> <pre>// 最好使用length屬性初始化第二個變量 var divs = document.getElementsByTagName("div"); var i, len, div; // len保存著第一次循環時div的數量,不會隨著循環增加 for (i=0, len=divs.length; i < len; i++) { div = document.createElement("div"); document.body.appendChild(div); }</pre> <p>盡量減少訪問<b>NodeList</b>的次數,因為每次訪問都會運行一次基于文檔的查詢。可以考慮將從<b>NodeList</b>中取得的值緩存起來。</p> <p>理解DOM的關鍵就是理解DOM對性能的影響。DOM操作往往是JavaScript程序中開銷最大的部分。有鑒于此,最好減少DOM操作。</p> </div> <div id="x7dfbjf" class="mt-64 tags-seach" > <div id="thrb7ld" class="tags-info"> <a style="width:120px;" title="GPU云服務器" href="http://specialneedsforspecialkids.com/site/product/gpu.html">GPU云服務器</a> <a style="width:120px;" title="云服務器" href="http://specialneedsforspecialkids.com/site/active/kuaijiesale.html?ytag=seo">云服務器</a> <a style="width:120px;" title="javascript高級程序設計第2版" href="http://specialneedsforspecialkids.com/yun/tag/javascriptgaojichengxushejidi2ban/">javascript高級程序設計第2版</a> <a style="width:120px;" title="javascript高級程序設計第三版" href="http://specialneedsforspecialkids.com/yun/tag/javascriptgaojichengxushejidisanban/">javascript高級程序設計第三版</a> <a style="width:120px;" title="明解c語言第9章" href="http://specialneedsforspecialkids.com/yun/tag/mingjiecyuyandi9zhang/">明解c語言第9章</a> <a style="width:120px;" title="javascript入門經典第5版" href="http://specialneedsforspecialkids.com/yun/tag/javascriptrumenjingdiandi5ban/">javascript入門經典第5版</a> </div> </div> <div id="7hfzxtr" class="entry-copyright mb-30"> <p class="mb-15"> 文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。</p> <p>轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109690.html</p> </div> <ul class="pre-next-page"> <li id="d77xvhz" class="ellipsis"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/109689.html">上一篇:一種只寫 SQL、做配置完成復雜業務系統開發的方法</a></li> <li id="bdlj75f" class="ellipsis"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/109691.html">下一篇:《ES6學習2》 變量的解構賦值</a></li> </ul> </div> <div id="r7zh5vn" class="about_topicone-mid"> <h3 class="top-com-title mb-0"><span data-id="0">相關文章</span></h3> <ul class="com_white-left-mid atricle-list-box"> <li> <div id="blhhv7t" class="atricle-list-right"> <h2 class="ellipsis2"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/104142.html"><b>《<em>JavaScript</em><em>高級</em><em><em>程序</em><em>設計</em></em>》(<em>第</em><em>3</em><em>版</em>)<em>讀書</em><em>筆記</em> <em>第</em>1~2<em>章</em></b></a></h2> <p class="ellipsis2 good">摘要:表示應該立即下載腳本,但不應妨礙頁面中的其他操作可選。表示通過屬性指定的代碼的字符集。表示腳本可以延遲到文檔完全被解析和顯示之后再執行。實際上,服務器在傳送文件時使用的類型通常是,但在中設置這個值卻可能導致腳本被忽略。 第1章 JavaScript 簡介 雖然JavaScript和ECMAScript通常被人們用來表達相同的含義,但JavaScript的含義比ECMA-262要多得多...</p> <div id="7zjh7vn" class="com_white-left-info"> <div id="plhbxbl" class="com_white-left-infol"> <a href="http://specialneedsforspecialkids.com/yun/u-486.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/04/small_000000486.jpg" alt=""><span id="pzxrd7t" class="layui-hide64">Corwien</span></a> <time datetime="">2019-08-23 17:18</time> <span><i class="fa fa-commenting"></i>評論0</span> <span><i class="fa fa-star"></i>收藏0</span> </div> </div> </div> </li> <li> <div id="tp5jrj7" class="atricle-list-right"> <h2 class="ellipsis2"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/109699.html"><b>《<em>JavaScript</em><em>高級</em><em><em>程序</em><em>設計</em></em>》(<em>第</em><em>3</em><em>版</em>)<em>讀書</em><em>筆記</em> <em>第</em>11<em>章</em> <em>DOM</em>拓展</b></a></h2> <p class="ellipsis2 good">摘要:對的兩個主要拓展是選擇和。以下插入標記的拓展已經納入了規范。在寫模式下,會根據指定的字符串創建新的子樹,然后用這個子樹完全替換調用元素。在刪除帶有時間處理程序或引用了其他對象子樹時,就有可能導致內存占用問題。 盡管DOM作為API已經非常完善了,但為了實現更多功能,仍然會有一些標準或專有的拓展。2008年之前,瀏覽器中幾乎所有的拓展都是專有的,此后W3C著手將一些已經成為事實標準的專...</p> <div id="vfrzjzh" class="com_white-left-info"> <div id="fbvh7t5" class="com_white-left-infol"> <a href="http://specialneedsforspecialkids.com/yun/u-1447.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/14/small_000001447.jpg" alt=""><span id="p57fnjb" class="layui-hide64">luck</span></a> <time datetime="">2019-08-26 13:52</time> <span><i class="fa fa-commenting"></i>評論0</span> <span><i class="fa fa-star"></i>收藏0</span> </div> </div> </div> </li> <li> <div id="nvrx5vp" class="atricle-list-right"> <h2 class="ellipsis2"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/104169.html"><b>《<em>JavaScript</em><em>高級</em><em><em>程序</em><em>設計</em></em>》(<em>第</em><em>3</em><em>版</em>)<em>讀書</em><em>筆記</em> <em>第</em>4<em>章</em> 變量、作用域和內存問題</b></a></h2> <p class="ellipsis2 good">摘要:具體說就是執行流進入下列任何一個語句時,作用域鏈就會得到加長語句的塊。如果局部環境中存在著同名的標識符,就不會使用位于父環境中的標識符訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 基本類型和引用類型的值 ECMAscript變量包含 基本類型值和引用類型值 基本類型值值的是基本數據類型:Undefined, Null, Boolean, Number, String ...</p> <div id="xtrdrjt" class="com_white-left-info"> <div id="zvhbzft" class="com_white-left-infol"> <a href="http://specialneedsforspecialkids.com/yun/u-324.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/03/small_000000324.jpg" alt=""><span id="ntnvzjh" class="layui-hide64">lidashuang</span></a> <time datetime="">2019-08-23 17:19</time> <span><i class="fa fa-commenting"></i>評論0</span> <span><i class="fa fa-star"></i>收藏0</span> </div> </div> </div> </li> <li> <div id="njh5vnh" class="atricle-list-right"> <h2 class="ellipsis2"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/82924.html"><b>Ajax與Comet-<em>JavaScript</em><em>高級</em><em><em>程序</em><em>設計</em></em><em>第</em>21<em>章</em><em>讀書</em><em>筆記</em>(1)</b></a></h2> <p class="ellipsis2 good">摘要:技術的核心是對象即。收到響應后,響應的數據會自動填充對象的屬性,相關的屬性有作為響應主體被返回的文本。收到響應后,一般來說,會先判斷是否為,這是此次請求成功的標志。中的版本會將設置為,而中原生的則會將規范化為。會在取得時報告的值為。 Ajax(Asynchronous Javascript + XML)技術的核心是XMLHttpRequest對象,即: XHR。雖然名字中包含XML,但...</p> <div id="tdzt7tp" class="com_white-left-info"> <div id="75jz5vd" class="com_white-left-infol"> <a href="http://specialneedsforspecialkids.com/yun/u-1549.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/15/small_000001549.jpg" alt=""><span id="7trrdvp" class="layui-hide64">imingyu</span></a> <time datetime="">2019-08-20 16:27</time> <span><i class="fa fa-commenting"></i>評論0</span> <span><i class="fa fa-star"></i>收藏0</span> </div> </div> </div> </li> <li> <div id="ldzvtxt" class="atricle-list-right"> <h2 class="ellipsis2"><a class="hpf" href="http://specialneedsforspecialkids.com/yun/109582.html"><b>《<em>JavaScript</em><em>高級</em><em><em>程序</em><em>設計</em></em>》(<em>第</em><em>3</em><em>版</em>)<em>讀書</em><em>筆記</em> <em>第</em>9<em>章</em> 客戶端檢測</b></a></h2> <p class="ellipsis2 good">摘要:用戶代理檢測用戶代理檢測是爭議最大的客戶端檢測技術。第二個要檢測是。由于實際的版本號可能會包含數字小數點和字母,所以捕獲組中使用了表示非空格的特殊字符。版本號不在后面,而是在后面。除了知道設備,最好還能知道的版本號。 檢測Web客戶端的手段很多,各有利弊,但不到萬不得已就不要使用客戶端檢測。只要能找到更通用的方法,就應該優先采用更通用的方法。一言蔽之,先設計最通用的方案,然后再使用特定...</p> <div id="rjf5btn" class="com_white-left-info"> <div id="7nlj5xl" class="com_white-left-infol"> <a href="http://specialneedsforspecialkids.com/yun/u-1394.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/13/small_000001394.jpg" alt=""><span id="hbhdlrx" class="layui-hide64">ispring</span></a> <time datetime="">2019-08-26 13:48</time> <span><i class="fa fa-commenting"></i>評論0</span> <span><i class="fa fa-star"></i>收藏0</span> </div> </div> </div> </li> </ul> </div> <div id="7xhtb5z" class="topicone-box-wangeditor"> <h3 class="top-com-title mb-64"><span>發表評論</span></h3> <div id="tz7nl5t" class="xcp-publish-main flex_box_zd"> <div id="v7jpztl" class="unlogin-pinglun-box"> <a href="javascript:login()" class="grad">登陸后可評論</a> </div> </div> </div> <div id="7jht7tn" class="site-box-content"> <div id="p7lxhzx" class="site-content-title"> <h3 class="top-com-title mb-64"><span>0條評論</span></h3> </div> <div id="zxfdfpz" class="pages"></ul></div> </div> </div> <div id="zv5tvzd" class="layui-col-md4 layui-col-lg3 com_white-right site-wrap-right"> <div id="tdz77hn" class=""> <div id="j75jhrj" class="com_layuiright-box user-msgbox"> <a href="http://specialneedsforspecialkids.com/yun/u-1200.html"><img src="http://specialneedsforspecialkids.com/yun/data/avatar/000/00/12/small_000001200.jpg" alt=""></a> <h3><a href="http://specialneedsforspecialkids.com/yun/u-1200.html" rel="nofollow">yearsj</a></h3> <h6>男<span>|</span>高級講師</h6> <div id="d7lztxd" class="flex_box_zd user-msgbox-atten"> <a href="javascript:attentto_user(1200)" id="attenttouser_1200" class="grad follow-btn notfollow attention">我要關注</a> <a href="javascript:login()" title="發私信" >我要私信</a> </div> <div id="7xlvpvb" class="user-msgbox-list flex_box_zd"> <h3 class="hpf">TA的文章</h3> <a href="http://specialneedsforspecialkids.com/yun/ut-1200.html" class="box_hxjz">閱讀更多</a> </div> <ul class="user-msgbox-ul"> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/130845.html">tensorflow用gpu</a></h3> <p>閱讀 2136<span>·</span>2023-04-26 00:23</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/119564.html">因算法出現歧視問題,Facebook 緊急下架相關話題推薦功能,</a></h3> <p>閱讀 807<span>·</span>2021-09-08 09:45</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/111177.html">CSS > 行內格式化上下文中的各種高度計算</a></h3> <p>閱讀 2435<span>·</span>2019-08-28 18:20</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/109690.html">《JavaScript高級程序設計》(第3版)讀書筆記 第10章 DOM</a></h3> <p>閱讀 2542<span>·</span>2019-08-26 13:51</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/106345.html">前端項目修改默認滾動條樣式</a></h3> <p>閱讀 1594<span>·</span>2019-08-26 10:32</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/106120.html">ES6之Proxy & Reflection API</a></h3> <p>閱讀 1391<span>·</span>2019-08-26 10:24</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/106100.html">理解Koa洋蔥模型</a></h3> <p>閱讀 2026<span>·</span>2019-08-26 10:23</p></li> <li><h3 class="ellipsis"><a href="http://specialneedsforspecialkids.com/yun/104769.html">JavaScript常用6大繼承方式解析</a></h3> <p>閱讀 2196<span>·</span>2019-08-23 18:10</p></li> </ul> </div> <!-- 文章詳情右側廣告--> <div id="hn5hptz" class="com_layuiright-box"> <h6 class="top-com-title"><span>最新活動</span></h6> <div id="fjjj55n" class="com_adbox"> <div id="d75n5pr" class="layui-carousel" id="right-item"> <div carousel-item> <div> <a href="http://specialneedsforspecialkids.com/site/active/kuaijiesale.html?ytag=seo" rel="nofollow"> <img src="http://specialneedsforspecialkids.com/yun/data/attach/240625/2rTjEHmi.png" alt="云服務器"> </a> </div> <div> <a href="http://specialneedsforspecialkids.com/site/product/gpu.html" rel="nofollow"> <img src="http://specialneedsforspecialkids.com/yun/data/attach/240807/7NjZjdrd.png" alt="GPU云服務器"> </a> </div> </div> </div> </div> <!-- banner結束 --> <div id="f7nl5pv" class="adhtml"> </div> <script> $(function(){ $.ajax({ type: "GET", url:"http://specialneedsforspecialkids.com/yun/ad/getad/1.html", cache: false, success: function(text){ $(".adhtml").html(text); } }); }) </script> </div> </div> </div> </div> </div> </section> <!-- wap拉出按鈕 --> <div id="t7trnjb" class="site-tree-mobile layui-hide"> <i class="layui-icon layui-icon-spread-left"></i> </div> <!-- wap遮罩層 --> <div id="fl5t7rl" class="site-mobile-shade"></div> <!--付費閱讀 --> <div class="hnlhrzj" id="payread"> <div id="jvv5zdl" class="layui-form-item">閱讀需要支付1元查看</div> <div id="fzlpl5h" class="layui-form-item"><button class="btn-right">支付并查看</button></div> </div> <script> var prei=0; $(".site-seo-depict pre").each(function(){ var html=$(this).html().replace("<code>","").replace("</code>","").replace('<code class="javascript hljs" codemark="1">',''); $(this).attr('data-clipboard-text',html).attr("id","pre"+prei); $(this).html("").append("<code>"+html+"</code>"); prei++; }) $(".site-seo-depict img").each(function(){ if($(this).attr("src").indexOf('data:image/svg+xml')!= -1){ $(this).remove(); } }) $("LINK[href*='style-49037e4d27.css']").remove(); $("LINK[href*='markdown_views-d7a94ec6ab.css']").remove(); layui.use(['jquery', 'layer','code'], function(){ $("pre").attr("class","layui-code"); $("pre").attr("lay-title",""); $("pre").attr("lay-skin",""); layui.code(); $(".layui-code-h3 a").attr("class","copycode").html("復制代碼 ").attr("onclick","copycode(this)"); }); function copycode(target){ var id=$(target).parent().parent().attr("id"); var clipboard = new ClipboardJS("#"+id); clipboard.on('success', function(e) { e.clearSelection(); alert("復制成功") }); clipboard.on('error', function(e) { alert("復制失敗") }); } //$(".site-seo-depict").html($(".site-seo-depict").html().slice(0, -5)); </script> <link rel="stylesheet" type="text/css" href="http://specialneedsforspecialkids.com/yun/static/js/neweditor/code/styles/tomorrow-night-eighties.css"> <script src="http://specialneedsforspecialkids.com/yun/static/js/neweditor/code/highlight.pack.js" type="text/javascript"></script> <script src="http://specialneedsforspecialkids.com/yun/static/js/clipboard.js"></script> <script>hljs.initHighlightingOnLoad();</script> <script> function setcode(){ var _html=''; document.querySelectorAll('pre code').forEach((block) => { var _tmptext=$.trim($(block).text()); if(_tmptext!=''){ _html=_html+_tmptext; console.log(_html); } }); } </script> <script> function payread(){ layer.open({ type: 1, title:"付費閱讀", shadeClose: true, content: $('#payread') }); } // 舉報 function jupao_tip(){ layer.open({ type: 1, title:false, shadeClose: true, content: $('#jubao') }); } $(".getcommentlist").click(function(){ var _id=$(this).attr("dataid"); var _tid=$(this).attr("datatid"); $("#articlecommentlist"+_id).toggleClass("hide"); var flag=$("#articlecommentlist"+_id).attr("dataflag"); if(flag==1){ flag=0; }else{ flag=1; //加載評論 loadarticlecommentlist(_id,_tid); } $("#articlecommentlist"+_id).attr("dataflag",flag); }) $(".add-comment-btn").click(function(){ var _id=$(this).attr("dataid"); $(".formcomment"+_id).toggleClass("hide"); }) $(".btn-sendartcomment").click(function(){ var _aid=$(this).attr("dataid"); var _tid=$(this).attr("datatid"); var _content=$.trim($(".commenttext"+_aid).val()); if(_content==''){ alert("評論內容不能為空"); return false; } var touid=$("#btnsendcomment"+_aid).attr("touid"); if(touid==null){ touid=0; } addarticlecomment(_tid,_aid,_content,touid); }) $(".button_agree").click(function(){ var supportobj = $(this); var tid = $(this).attr("id"); $.ajax({ type: "GET", url:"http://specialneedsforspecialkids.com/yun/index.php?topic/ajaxhassupport/" + tid, cache: false, success: function(hassupport){ if (hassupport != '1'){ $.ajax({ type: "GET", cache:false, url: "http://specialneedsforspecialkids.com/yun/index.php?topic/ajaxaddsupport/" + tid, success: function(comments) { supportobj.find("span").html(comments+"人贊"); } }); }else{ alert("您已經贊過"); } } }); }); function attenquestion(_tid,_rs){ $.ajax({ //提交數據的類型 POST GET type:"POST", //提交的網址 url:"http://specialneedsforspecialkids.com/yun/favorite/topicadd.html", //提交的數據 data:{tid:_tid,rs:_rs}, //返回數據的格式 datatype: "json",//"xml", "html", "script", "json", "jsonp", "text". //在請求之前調用的函數 beforeSend:function(){}, //成功返回之后調用的函數 success:function(data){ var data=eval("("+data+")"); console.log(data) if(data.code==2000){ layer.msg(data.msg,function(){ if(data.rs==1){ //取消收藏 $(".layui-layer-tips").attr("data-tips","收藏文章"); $(".layui-layer-tips").html('<i class="fa fa-heart-o"></i>'); } if(data.rs==0){ //收藏成功 $(".layui-layer-tips").attr("data-tips","已收藏文章"); $(".layui-layer-tips").html('<i class="fa fa-heart"></i>') } }) }else{ layer.msg(data.msg) } } , //調用執行后調用的函數 complete: function(XMLHttpRequest, textStatus){ postadopt=true; }, //調用出錯執行的函數 error: function(){ //請求出錯處理 postadopt=false; } }); } </script> <footer> <div id="ndz75pn" class="layui-container"> <div id="ntfpph5" class="flex_box_zd"> <div id="7pjv5d5" class="left-footer"> <h6><a href="http://specialneedsforspecialkids.com/"><img src="http://specialneedsforspecialkids.com/yun/static/theme/ukd//images/logo.png" alt="UCloud (優刻得科技股份有限公司)"></a></h6> <p>UCloud (優刻得科技股份有限公司)是中立、安全的云計算服務平臺,堅持中立,不涉足客戶業務領域。公司自主研發IaaS、PaaS、大數據流通平臺、AI服務平臺等一系列云計算產品,并深入了解互聯網、傳統企業在不同場景下的業務需求,提供公有云、混合云、私有云、專有云在內的綜合性行業解決方案。</p> </div> <div id="hn7j5zh" class="right-footer layui-hidemd"> <ul class="flex_box_zd"> <li> <h6>UCloud與云服務</h6> <p><a href="http://specialneedsforspecialkids.com/site/about/intro/">公司介紹</a></p> <p><a >加入我們</a></p> <p><a href="http://specialneedsforspecialkids.com/site/ucan/onlineclass/">UCan線上公開課</a></p> <p><a href="http://specialneedsforspecialkids.com/site/solutions.html" >行業解決方案</a></p> <p><a href="http://specialneedsforspecialkids.com/site/pro-notice/">產品動態</a></p> </li> <li> <h6>友情鏈接</h6> <p><a >GPU算力平臺</a></p> <p><a >UCloud私有云</a></p> <p><a >SurferCloud</a></p> <p><a >工廠仿真軟件</a></p> <p><a >Pinex</a></p> <p><a >AI繪畫</a></p> </li> <li> <h6>社區欄目</h6> <p><a href="http://specialneedsforspecialkids.com/yun/column/index.html">專欄文章</a></p> <p><a href="http://specialneedsforspecialkids.com/yun/udata/">專題地圖</a></p> </li> <li> <h6>常見問題</h6> <p><a href="http://specialneedsforspecialkids.com/site/ucsafe/notice.html" >安全中心</a></p> <p><a href="http://specialneedsforspecialkids.com/site/about/news/recent/" >新聞動態</a></p> <p><a href="http://specialneedsforspecialkids.com/site/about/news/report/">媒體動態</a></p> <p><a href="http://specialneedsforspecialkids.com/site/cases.html">客戶案例</a></p> <p><a href="http://specialneedsforspecialkids.com/site/notice/">公告</a></p> </li> <li> <span><img src="https://static.ucloud.cn/7a4b6983f4b94bcb97380adc5d073865.png" alt="優刻得"></span> <p>掃掃了解更多</p></div> </div> <div id="fx5pnfn" class="copyright">Copyright ? 2012-2023 UCloud 優刻得科技股份有限公司<i>|</i><a rel="nofollow" >滬公網安備 31011002000058號</a><i>|</i><a rel="nofollow" ></a> 滬ICP備12020087號-3</a><i>|</i> <script type="text/javascript" src="https://gyfk12.kuaishang.cn/bs/ks.j?cI=197688&fI=125915" charset="utf-8"></script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?290c2650b305fc9fff0dbdcafe48b59d"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-DZSMXQ3P9N"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-DZSMXQ3P9N'); </script> <script> (function(){ var el = document.createElement("script"); el.src = "https://lf1-cdn-tos.bytegoofy.com/goofy/ttzz/push.js?99f50ea166557aed914eb4a66a7a70a4709cbb98a54ecb576877d99556fb4bfc3d72cd14f8a76432df3935ab77ec54f830517b3cb210f7fd334f50ccb772134a"; el.id = "ttzz"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(el, s); })(window) </script></div> </div> </footer> <footer> <div class="friendship-link"> <p>感谢您访问我们的网站,您可能还对以下资源感兴趣:</p> <a href="http://specialneedsforspecialkids.com/" title="国产xxxx99真实实拍">国产xxxx99真实实拍</a> <div class="friend-links"> <a href="http://belistarlp.com/">国产黄色在线</a> </div> </div> </footer> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body><div id="d57b5" class="pl_css_ganrao" style="display: none;"><em id="d57b5"><div id="d57b5"><ol id="d57b5"><form id="d57b5"></form></ol></div></em><ol id="d57b5"></ol><nobr id="d57b5"></nobr><sup id="d57b5"></sup><thead id="d57b5"><big id="d57b5"><dl id="d57b5"><pre id="d57b5"></pre></dl></big></thead><strong id="d57b5"></strong><ol id="d57b5"><i id="d57b5"></i></ol><sup id="d57b5"></sup><address id="d57b5"><legend id="d57b5"></legend></address><small id="d57b5"><menuitem id="d57b5"></menuitem></small><sub id="d57b5"></sub><nobr id="d57b5"><em id="d57b5"><meter id="d57b5"><pre id="d57b5"></pre></meter></em></nobr><b id="d57b5"><progress id="d57b5"></progress></b><ruby id="d57b5"><sub id="d57b5"></sub></ruby><font id="d57b5"><div id="d57b5"><ol id="d57b5"><style id="d57b5"></style></ol></div></font><ol id="d57b5"><style id="d57b5"></style></ol><pre id="d57b5"></pre><p id="d57b5"></p><sup id="d57b5"></sup><mark id="d57b5"><form id="d57b5"><p id="d57b5"><var id="d57b5"></var></p></form></mark><sup id="d57b5"><form id="d57b5"><rp id="d57b5"><font id="d57b5"></font></rp></form></sup><tt id="d57b5"><mark id="d57b5"><form id="d57b5"><p id="d57b5"></p></form></mark></tt><output id="d57b5"></output><small id="d57b5"></small><dl id="d57b5"></dl><tt id="d57b5"></tt><small id="d57b5"><menuitem id="d57b5"></menuitem></small><span id="d57b5"><strike id="d57b5"><label id="d57b5"><strong id="d57b5"></strong></label></strike></span><small id="d57b5"><menuitem id="d57b5"></menuitem></small><thead id="d57b5"></thead><small id="d57b5"></small><th id="d57b5"></th><dl id="d57b5"></dl><meter id="d57b5"></meter><tt id="d57b5"></tt><ruby id="d57b5"></ruby><optgroup id="d57b5"></optgroup><track id="d57b5"><thead id="d57b5"></thead></track><b id="d57b5"></b><form id="d57b5"><rp id="d57b5"><font id="d57b5"><meter id="d57b5"></meter></font></rp></form><ins id="d57b5"></ins><address id="d57b5"><legend id="d57b5"></legend></address><th id="d57b5"><thead id="d57b5"><big id="d57b5"><acronym id="d57b5"></acronym></big></thead></th><sub id="d57b5"><thead id="d57b5"></thead></sub><sub id="d57b5"></sub><thead id="d57b5"></thead><output id="d57b5"></output><b id="d57b5"></b><form id="d57b5"><p id="d57b5"><var id="d57b5"><label id="d57b5"></label></var></p></form><ins id="d57b5"><address id="d57b5"><legend id="d57b5"><ol id="d57b5"></ol></legend></address></ins><menuitem id="d57b5"><pre id="d57b5"></pre></menuitem><tt id="d57b5"><progress id="d57b5"><acronym id="d57b5"><legend id="d57b5"></legend></acronym></progress></tt><sup id="d57b5"></sup><thead id="d57b5"><big id="d57b5"></big></thead><address id="d57b5"><legend id="d57b5"></legend></address><p id="d57b5"><var id="d57b5"></var></p><b id="d57b5"></b><form id="d57b5"><legend id="d57b5"><dfn id="d57b5"><u id="d57b5"></u></dfn></legend></form><tt id="d57b5"><big id="d57b5"><acronym id="d57b5"><p id="d57b5"></p></acronym></big></tt><listing id="d57b5"><em id="d57b5"></em></listing><sub id="d57b5"></sub><pre id="d57b5"><th id="d57b5"><b id="d57b5"><mark id="d57b5"></mark></b></th></pre><font id="d57b5"></font><pre id="d57b5"><style id="d57b5"><listing id="d57b5"><dfn id="d57b5"></dfn></listing></style></pre><ins id="d57b5"><form id="d57b5"></form></ins><legend id="d57b5"></legend><div id="d57b5"></div><nobr id="d57b5"></nobr><sub id="d57b5"><thead id="d57b5"></thead></sub><thead id="d57b5"><thead id="d57b5"><label id="d57b5"><pre id="d57b5"></pre></label></thead></thead><small id="d57b5"></small><label id="d57b5"></label><output id="d57b5"><span id="d57b5"><strike id="d57b5"><strong id="d57b5"></strong></strike></span></output><legend id="d57b5"><sup id="d57b5"><label id="d57b5"><video id="d57b5"></video></label></sup></legend><form id="d57b5"></form><dl id="d57b5"></dl><strong id="d57b5"><track id="d57b5"></track></strong><address id="d57b5"></address><output id="d57b5"><span id="d57b5"><strike id="d57b5"><label id="d57b5"></label></strike></span></output><dfn id="d57b5"></dfn><i id="d57b5"><nobr id="d57b5"><small id="d57b5"><output id="d57b5"></output></small></nobr></i><nobr id="d57b5"><em id="d57b5"><meter id="d57b5"><span id="d57b5"></span></meter></em></nobr><i id="d57b5"><listing id="d57b5"></listing></i><pre id="d57b5"><i id="d57b5"></i></pre><meter id="d57b5"><ol id="d57b5"><style id="d57b5"><listing id="d57b5"></listing></style></ol></meter><track id="d57b5"></track><nobr id="d57b5"></nobr><ol id="d57b5"></ol><p id="d57b5"><var id="d57b5"></var></p><p id="d57b5"></p><thead id="d57b5"><label id="d57b5"><optgroup id="d57b5"><track id="d57b5"></track></optgroup></label></thead><legend id="d57b5"></legend><listing id="d57b5"><dfn id="d57b5"></dfn></listing><dl id="d57b5"><pre id="d57b5"></pre></dl><form id="d57b5"><p id="d57b5"><var id="d57b5"><u id="d57b5"></u></var></p></form><strike id="d57b5"></strike><menuitem id="d57b5"></menuitem><address id="d57b5"><p id="d57b5"></p></address><small id="d57b5"></small><video id="d57b5"><font id="d57b5"><div id="d57b5"><ol id="d57b5"></ol></div></font></video><form id="d57b5"></form><strong id="d57b5"></strong><optgroup id="d57b5"><output id="d57b5"><sub id="d57b5"><thead id="d57b5"></thead></sub></output></optgroup><thead id="d57b5"><big id="d57b5"><dl id="d57b5"><pre id="d57b5"></pre></dl></big></thead><sub id="d57b5"></sub><ol id="d57b5"><style id="d57b5"></style></ol><address id="d57b5"><legend id="d57b5"></legend></address><tt id="d57b5"><big id="d57b5"><dl id="d57b5"><legend id="d57b5"></legend></dl></big></tt><strike id="d57b5"></strike><i id="d57b5"><listing id="d57b5"><small id="d57b5"><output id="d57b5"></output></small></listing></i><style id="d57b5"></style><strong id="d57b5"></strong><u id="d57b5"><rp id="d57b5"><address id="d57b5"><div id="d57b5"></div></address></rp></u><p id="d57b5"><var id="d57b5"></var></p><progress id="d57b5"><acronym id="d57b5"><legend id="d57b5"><var id="d57b5"></var></legend></acronym></progress><b id="d57b5"><progress id="d57b5"></progress></b><pre id="d57b5"><i id="d57b5"><nobr id="d57b5"><optgroup id="d57b5"></optgroup></nobr></i></pre><ins id="d57b5"><address id="d57b5"></address></ins><label id="d57b5"></label><progress id="d57b5"></progress><output id="d57b5"><sub id="d57b5"><strike id="d57b5"><label id="d57b5"></label></strike></sub></output><ins id="d57b5"></ins><p id="d57b5"><var id="d57b5"></var></p><font id="d57b5"></font><ol id="d57b5"><style id="d57b5"></style></ol><label id="d57b5"><video id="d57b5"></video></label><progress id="d57b5"><acronym id="d57b5"></acronym></progress><b id="d57b5"><mark id="d57b5"></mark></b><b id="d57b5"><progress id="d57b5"></progress></b><form id="d57b5"><legend id="d57b5"></legend></form><listing id="d57b5"><small id="d57b5"><menuitem id="d57b5"><sub id="d57b5"></sub></menuitem></small></listing><thead id="d57b5"><thead id="d57b5"></thead></thead><form id="d57b5"><ins id="d57b5"></ins></form><dfn id="d57b5"><b id="d57b5"><mark id="d57b5"><address id="d57b5"></address></mark></b></dfn><ol id="d57b5"><label id="d57b5"></label></ol><u id="d57b5"><ins id="d57b5"></ins></u><dl id="d57b5"><pre id="d57b5"></pre></dl><pre id="d57b5"></pre><form id="d57b5"><legend id="d57b5"></legend></form><em id="d57b5"><meter id="d57b5"></meter></em><pre id="d57b5"></pre><sub id="d57b5"><strike id="d57b5"></strike></sub><dfn id="d57b5"><b id="d57b5"></b></dfn><output id="d57b5"><span id="d57b5"></span></output><sup id="d57b5"><form id="d57b5"></form></sup><label id="d57b5"><pre id="d57b5"></pre></label><strong id="d57b5"></strong><mark id="d57b5"></mark><pre id="d57b5"><track id="d57b5"><tt id="d57b5"><mark id="d57b5"></mark></tt></track></pre><em id="d57b5"><menuitem id="d57b5"></menuitem></em></div> <script src="http://specialneedsforspecialkids.com/yun/static/theme/ukd/js/common.js"></script> <<script type="text/javascript"> $(".site-seo-depict *,.site-content-answer-body *,.site-body-depict *").css("max-width","100%"); </script> </html>