国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript操作HTML DOM節點的基礎教程

2019-11-20 10:23:55
字體:
來源:轉載
供稿:網友

因為 DOM 的存在,這使我們可以通過 JavaScript 來獲取、創建、修改、或刪除節點。
NOTE:下面提供的例子中的 element 均為元素節點。
獲取節點

父子關系

element.parentNodeelement.firstChild/element.lastChildelement.childNodes/element.children

兄弟關系

element.previousSibling/element.nextSiblingelement.previousElementSibling/element.nextElementSibling

通過節點直接的關系獲取節點會導致代碼維護性大大降低(節點之間的關系變化會直接影響到獲取節點),而通過接口則可以有效的解決此問題。

通過節點直接的關系獲取節點會導致代碼維護性大大降低(節點之間的關系變化會直接影響到獲取節點),而通過接口則可以有效的解決此問題。

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>ELEMENT_NODE & TEXT_NODE</title></head><body> <ul id="ul"> <li>First</li> <li>Second</li> <li>Third</li> <li>Fourth</li> </ul> <p>Hello</p> <script type="text/javascript"> var ulNode = document.getElementsByTagName("ul")[0]; console.log(ulNode.parentNode);    //<body></body> console.log(ulNode.previousElementSibling); //null console.log(ulNode.nextElementSibling);  //<p>Hello</p> console.log(ulNode.firstElementChild);  //<li>First</li> console.log(ulNode.lastElementChild);  //<li>Fourth</li> </script></body></html>

NTOE:細心的人會發現,在節點遍歷的例子中,body、ul、li、p節點之間是沒有空格的,因為如果有空格,那么空格就會被當做一個TEXT節點,從而用ulNode.previousSibling獲取到得就是一個空的文本節點,而不是 <li>First</li> 節點了。即節點遍歷的幾個屬性會得到所有的節點類型,而元素遍歷只會得到相對應的元素節點。一般情況下,用得比較多得還是元素節點的遍歷屬性。
實現瀏覽器兼容版的element.children
有一些低版本的瀏覽器并不支持 element.children 方法,但我們可以用下面的方式來實現兼容。

<html lang><head> <meta charest="utf-8"> <title>Compatible Children Method</title></head><body id="body"> <div id="item"> <div>123</div> <p>ppp</p> <h1>h1</h1> </div> <script type="text/javascript"> function getElementChildren(e){  if(e.children){  return e.children;  }else{  /* compatible other browse */  var i, len, children = [];  var child = element.firstChild;  if(child != element.lastChild){   while(child != null){   if(child.nodeType == 1){    children.push(child);   }   child = child.nextSibling;   }  }else{   children.push(child);  }  return children;  } } /* Test method getElementChildren(e) */ var item = document.getElementById("item"); var children = getElementChildren(item); for(var i =0; i < children.length; i++){  alert(children[i]); } </script></body></html>

NOTE:此兼容方法為初稿,還未進行兼容性測試。
接口獲取元素節點

getElementByIdgetElementsByTagNamegetElementsByClassNamequerySelectorquerySelectorAll

2016311163518624.png (793×256)

getElementById

獲取文檔中指定 id 的節點對象。

var element = document.getElementById('id');getElementsByTagName

動態的獲取具有指定標簽元素節點的集合(其返回值會被 DOM 的變化所影響,其值會發生變化)。此接口可直接通過元素而獲取,不必直接作用于 document 之上。

// 示例var collection = element.getElementsByTagName('tagName');// 獲取指定元素的所有節點var allNodes = document.getElementsByTagName('*');// 獲取所有 p 元素的節點var elements = document.getElementsByTagName('p');// 取出第一個 p 元素var p = elements[0];


getElementsByClassName
獲取指定元素中具有指定 class 的所有節點。多個 class 可的選擇可使用空格分隔,與順序無關。
var elements = element.getElementsByClassName('className');
NOTE:IE9 及一下版本不支持 getElementsByClassName
兼容方法

function getElementsByClassName(root, className) { // 特性偵測 if (root.getElementsByClassName) { // 優先使用 W3C 規范接口 return root.getElementsByClassName(className); } else { // 獲取所有后代節點 var elements = root.getElementsByTagName('*'); var result = []; var element = null; var classNameStr = null; var flag = null; className = className.split(' '); // 選擇包含 class 的元素 for (var i = 0, element; element = elements[i]; i++) {  classNameStr = ' ' + element.getAttribute('class') + ' ';  flag = true;  for (var j = 0, name; name = className[j]; j++) {  if (classNameStr.indexOf(' ' + name + ' ') === -1) {   flag = false;   break;  }  }  if (flag) {  result.push(element);  } } return result; }}

querySelector / querySelectorAll

獲取一個 list (其返回結果不會被之后 DOM 的修改所影響,獲取后不會再變化)符合傳入的 CSS 選擇器的第一個元素或全部元素。

var listElementNode = element.querySelector('selector');var listElementsNodes = element.querySelectorAll('selector');var sampleSingleNode = element.querySelector('#className');var sampleAllNodes = element.querySelectorAll('#className');

NOTE: IE9 一下不支持 querySelector 與 querySelectorAll
創建節點

創建節點 -> 設置屬性 -> 插入節點

var element = document.createElement('tagName');

修改節點

textContent
獲取或設置節點以及其后代節點的文本內容(對于節點中的所有文本內容)。

element.textContent; // 獲取element.textContent = 'New Content';

NOTE:不支持 IE 9 及其一下版本。
innerText (不符合 W3C 規范)
獲取或設置節點以及節點后代的文本內容。其作用于 textContent 幾乎一致。

element.innerText;

NOTE:不符合 W3C 規范,不支持 FireFox 瀏覽器。
FireFox 兼容方案

if (!('innerText' in document.body)) { HTMLElement.prototype.__defineGetter__('innerText', function(){ return this.textContent; }); HTMLElement.prototype.__defineSetter__('innerText', function(s) { return this.textContent = s; });}

插入節點

appendChild

在指定的元素內追加一個元素節點。

var aChild = element.appendChild(aChild);

insertBefore

在指定元素的指定節點前插入指定的元素。

var aChild = element.insertBefore(aChild, referenceChild);

刪除節點

刪除指定的節點的子元素節點。

var child = element.removeChild(child);

innerHTML

獲取或設置指定節點之中所有的 HTML 內容。替換之前內部所有的內容并創建全新的一批節點(去除之前添加的事件和樣式)。innerHTML 不檢查內容,直接運行并替換原先的內容。
NOTE:只建議在創建全新的節點時使用。不可在用戶可控的情況下使用。

var elementsHTML = element.innerHTML;

存在的問題+

  • 低版本 IE 存在內存泄露
  • 安全問題(用戶可以在名稱中運行腳本代碼)

PS: appendChild() , insertBefore()插入節點需注意的問題
使用appendChild()和insertBefore()插入節點都會返回給插入的節點,

//由于這兩種方法操作的都是某個節點的子節點,所以必須現取得父節點,代碼中 someNode 表示父節點 //使用appendChild()方法插入節點 var returnedNode = someNode.appendChild(newNode); alert(returnedNode == newNode) //true  //使用insertBefore()方法插入節點 var returnedNode = someNode.appendChild(newNode); alert(returnedNode == newNode) //true 

 值得注意的是,如果這兩種方法插入的節點原本已經存在與文檔樹中,那么該節點將會被移動到新的位置,而不是被復制。

<div id="test">  <div>adscasdjk</div>   <div id="a">adscasdjk</div> </div> <script type="text/javascript">  var t = document.getElementById("test");  var a = document.getElementById('a');  //var tt = a.cloneNode(true);  t.appendChild(a); </script> 

在這段代碼中,頁面輸出的結果和沒有Javascript時是一樣的,元素并沒有被復制,由于元素本來就在最后一個位置,所以就和沒有操作一樣。如果把id為test的元素的兩個子元素點換位置,就可以在firbug中看到這兩個div已經被調換了位置。
如果我們希望把id為a的元素復制一個,然后添加到文檔中,那么必須使被復制的元素現脫離文檔流。這樣被添加復制的節點被添加到文檔中之后就不會影響到文檔流中原本的節點。即我們可以把復制的元素放到文檔的任何地方,而不影響被復制的元素。下面使用了cloneNode()方法,實現節點的深度復制,使用這種方法復制的節點會脫離文檔流。當然,我不建議使用這種方法復制具有id屬性的元素。因為在文檔中id值是唯一的。

<div id="test">  <div>adscasdjk</div>   <div id="a">adscasdjk</div> </div> <script type="text/javascript">  var t = document.getElementById("test");  var a = document.getElementById('a');  var tt = a.cloneNode(true);  t.appendChild(tt); </script> 

相似的操作方法還有 removeNode(node)刪除一個節點,并返回該節;replaceNode(newNode,node)替換node節點,并返回該節點。這兩種方法相對來說更容易使用一些。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁城县| 马龙县| 封丘县| 武平县| 广南县| 临沧市| 富蕴县| 十堰市| 桐梓县| 小金县| 贵定县| 资溪县| 盐城市| 铜梁县| 卢湾区| 扬州市| 灵武市| 白水县| 安岳县| 大悟县| 和林格尔县| 城步| 长泰县| 禄丰县| 安西县| 古田县| 巢湖市| 松阳县| 怀远县| 广水市| 上蔡县| 东平县| 登封市| 萍乡市| 岳普湖县| 泗水县| 公安县| 海阳市| 通山县| 涡阳县| 呼伦贝尔市|