JS DOM操做(建立、遍歷、獲取、操做、刪除節點)

建立節點css

 <!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>create方法</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        // 建立註釋節點
        var comment = document.createComment("A comment");
        // 建立文檔片斷
        var fragment = document.createDocumentFragment();

        var ul = document.getElementById("myList");
        var li = null;
        for (var i = 0; i < 3; i++){
          // 建立元素節點
          li = document.createElement("li");
          // 添加建立好的文本節點
          li.appendChild(document.createTextNode("Item " + (i+1)));
          fragment.appendChild(li);
        }
        ul.appendChild(fragment);
        // 插入註釋節點
        document.body.insertBefore(comment, document.body.firstChild);
      });
    </script>
  </head>
  <body>
    <ul id="myList"></ul>
  </body>
</html>

html5shivhtml

      (function() {
        if (! 
        /*@cc_on!@*/
        0) return;
        var e = "abbr, article, aside, audio, canvas, datalist, details, dialog, eventsource, figure, footer, header, hgroup, mark, menu, meter, nav, output, progress, section, time, video".split(', ');
        var i = e.length;
        while (i--){
          document.createElement(e[i]);
        }
      })();

建立節點createElement:html5

它的的參數能夠是大小也能夠是小寫,可是多數狀況下咱們使用小寫node

document.createElement()建立的HTML5標籤是能夠兼容IE8如下的瀏覽器的正則表達式

 


 

 

高效建立節點innerHTML-outerHTMLcanvas

      // innerHTML的限制:
      // 字符串最左邊不能出現空白,不然會被移除
      // 多數瀏覽器不會對script腳本進行執行
      // 不能單首創建meta/style/link等
      myReady(function(){
        var content = document.getElementById("content");
        var str = "<p>This is a <strong>paragraph</strong> with a list following it.</p>"
                    + "<ul>"
                    + "<li>Item 1</li>"
                    + "<li>Item 2</li>"
                    + "<li>Item 3</li>"
                    + "</ul>";
        content.innerHTML = str;
        alert(content.innerHTML);
      });

多數瀏覽器不會對script腳本進行執行數組

解決:添加defer屬性瀏覽器

放在有做用域的元素以後app

        var content = document.getElementById("content");
        var str = "<input type=\"hidden\"><script defer>alert('hi');<\/script>";
        content.innerHTML = str;
      });

建立style時解決IE兼容dom

        var content = document.getElementById("content");
        var str = "_<style type=\"text/css\">body {background-color: red; }</style>";
        content.innerHTML = str;
        // 移除最開頭添加的_
        content.removeChild(content.firstChild);
      });

innerText

        // innerText兼容火狐寫法:textContent
        var content = document.getElementById("content");
        function getInnerText(element){
          return typeof (element.textContent == "string") ? element.textContent : element.innerText;
        }
        function setInnerText(element, text){
          if (typeof element.textContent == "string"){
            element.textContent = text;
          } else {
            element.innerText = text;
          }
        }
        setInnerText(content, "Hello world!");
        console.log(getInnerText(content));

節點遍歷(查找節點)

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>dom Tree walker</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        // documentElement返回文檔根節點
        var oHtml = document.documentElement;
        var p = document.getElementById("paragraph");
        var txt = p.childNodes[0];

        // 獲取head節點三種方法
        var oHead = oHtml.firstChild;
        var oHead = oHtml.childNodes[0];
        var oHead = oHtml.childNodes.item(0);

        // 獲取body節點的兩種方法
        var oBody = oHtml.childNodes.item(1);
        var oBody = oHtml.childNodes[1];

        console.log(oHead.parentNode == oHtml);
        console.log(oBody.parentNode == oHtml);

        // 上一個兄弟元素
        console.log(oBody.previousSibling == oHead);
        // 下一個兄弟元素
        console.log(oHead.nextSibling == oBody);

        console.log(oBody);
        console.log(oHead);
        console.log(oHtml.tagName);//HTML

        // 經過p節點找到document節點
        console.log(p.ownerDocument == document);
        // 是否有子節點
        console.log(p.hasChildNodes());
        console.log(txt.hasChildNodes());
      });
    </script>
  </head><body>
    <p id="paragraph">文本葉子節點</p>
  </body>
</html>

 

 

輸出分別是:false/true/false

一、 首先區分firstChild和childNodes的區別

firstChild表示第一個子節點, 這個子節點包括元素節點,文本節點或者註釋節點

childNodes 返回節點的子節點集合,包括元素節點、文本節點還有屬性節點。 

二、分析這題的代碼

 第一個ul的第一個子節點是一個空的文本節點,也就是ul和li的換行,他是沒有子節點的,因此爲false

 第一個ul的第二個子節點是第一個li,有子節點,因此爲true

 第二個ul的第一個li,沒有子節點,因此爲false

 


 

 

打印HTML結構樹:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>DOM Travel</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        var s = "";
        // space存儲節點間分隔的字符串
        // node保存遍歷的當前節點
        function travel(space, node) {
          if (node.tagName) { // 若是當前節點是標籤,不是空的,就拼接字符串
            s += space + node.tagName + "<br/>";
          }
          var len = node.childNodes.length; //保存當前節點的子節點的個數
          for (var i = 0; i < len; i++) { //遍歷節點的子節點
            // 遞歸調用travel()
            travel(space + "|-", node.childNodes[i]); 
          }
        }
        travel("", document);
        document.write(s);
      });
    </script>
  </head>
  <body>
    <form>  
        <input type="button" id="button1" name="button1" value="Click Me!" />  
    </form>
  </body>
</html>

 

 

解決空白節點問題方法一:

1 元素節點

2 屬性節點

3 文本節點

        var box = document.getElementById("box");
        for(var i = 0, len = box.childNodes.length; i < len; i++) {
          if (box.childNodes[i].nodeType == 1) {
            // 只輸出元素節點(過濾文本節點)
            console.log(box.childNodes[i]);
          }
        }

解決空白節點問題方法二:

firstElementChild第一個元素節點

lastElementChild

nextElementSibling下一個兄弟元素節點

previoustElementSibling

childElementCount 全部直接子元素節點的個數

        var box = document.getElementById("box");
        for(var i = 0, len = box.childElementCount; i < len; i++) {
          console.log(box.children[i]);
        }

類數組對象nodeList

類數組對象沒法使用數組方法

將類數組對象轉爲數組

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>NodeList對象的特色</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        var box = document.getElementById("box");
        var nodes = box.childNodes;

        // 類數組對象沒法使用數組方法
        console.log(nodes);
        console.log(nodes[1]);
        nodes.push("<li>節點四</li>");

        // 將類數組對象轉爲數組兼容IE的寫法
        function makeArray(nodeList){
          var arr = null;
          try {
            // 將類數組對象轉爲數組
            return Array.prototype.slice.call(nodeList);
          }catch (e){
            arr = new Array();
            for(var i = 0, len = nodeList.length; i < len; i++){
              arr.push(nodeList[i]);
            }
          }
          return arr;
        }

        var newNodeList = makeArray(nodes);
        newNodeList.push("<li>節點四</li>");
        console.log(newNodeList);
      });
    </script>
  </head>
  <body>
    <ul id="box">  
      <li>節點一</li>
      <li>節點二</li>
      <li>節點三</li>  
    </ul>
  </body>
</html>

類數組對象HTMLCollection

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>類數組對象HTMLCollection</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        var scripts = document.scripts;
        var links = document.links;
        // 表格元素
        var cells = document.getElementById("tr").cells;
        // var imgs = document.images;
        var forms = document.forms;
        var options = document.getElementById("select").options;
        var ps = document.getElementsByTagName("p");

        console.log(scripts);
        console.log(links);
        console.log(cells);
        // console.log(imgs);
        console.log(forms);
        console.log(options);
        console.log(ps);

        //HTMLCollection對象的namedItem()方法
        //返回集合中具備指定name屬性或id屬性的元素
        console.log(cells.namedItem('td'));
      });
    </script>
  </head>
  <body>
    <ul id="box">
      <li>節點一</li>
      <li>節點二</li>
      <li>節點三</li>
    </ul>

    <table border="1">
      <tr id="tr">
        <td id="td">第一行</td>
        <td name="td">第二行</td>
        <td name="td">第三行</td>
      </tr>
    </table>

   <!--  <img src="duer.jpg" alt="img1" />
    <img src="ipone6s+.png" alt="img2" /> -->

    <form action="">
      <input type="text" value="用戶名">
    </form>
    <form action="">
      <input type="text" value="密碼">
    </form>

    <a href="#">忘記密碼</a>
    <a href="#">更多內容</a>

    <select id="select">
      <option value="0">北京</option>
      <option value="1">天津</option>
      <option value="2">河北</option>
    </select>

    <p>DOM探索之基礎詳解篇</p>
    <p>DOM探索之節點操做篇</p>
  </body>
</html>

類數組對象NamedNodeMap

返回attr屬性相關信息

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>類數組對象NamedNodeMap</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        var box = document.getElementById("box");
        var attrs = box.attributes;
        console.log(attrs);
        console.log(attrs.length);
        console.log(attrs[0]);
        console.log(attrs.item(1));
      });
    </script>
  </head>
  <body>
    <ul id="box" data-url="index.html" node-action="submit">
      <li>節點一</li>
      <li>節點二</li>
      <li>節點三</li>
    </ul>
  </body>
</html>

類數組對象具備動態性

        var divs = document.getElementsByTagName("div");
        // 先把最初的長度記錄在變量裏,防止後期動態改變
        var length = divs.length;
        var i = 0;
        while(i < length){
          document.body.appendChild(document.createElement("div"));
          i++;
        }

獲取節點

getElementsByName()方法必須在document後使用

// 獲取全部的元素
var all = document.getElementsByTagName('*');

getElementsByClassName()兼容性問題解決:

封裝函數:

// 函數用於選取符合標籤名的元素
var getElementsByClassName = function(opts) {
    var searchClass = opts.searchClass; // 存儲要查找的類名
    var node = opts.node || document;  // 存儲要出查找的範圍
    var tag = opts.tag || '*'; // 存儲必定範圍內要查找的標籤
    var result = [];
        // 判斷瀏覽器支不支持getElementsByClassName方法
    if (document.getElementsByClassName) { // 若是瀏覽器支持
        var nodes = node.getElementsByClassName(searchClass);
        if (tag !== "*") {
            for (var i = 0; node = nodes[i++];) {
                if (node.tagName === tag.toUpperCase()) {
                    result.push(node);
                }
            }
        } else { 
            result = nodes;
        }
        return result;
    } else { // 使用IE8如下的瀏覽器可以支持該屬性
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var i, j;
        var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
            if (pattern.test(els[i].className)) { // 檢測正則表達式
                result[j] = els[i];
                j++;
            }
        }
        return result;
    }
}

頁面調用:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>getElementsByClassName() 兼容瀏覽器方案</title>
    <script src="domReady.js"></script>
    <script src="getElementsByClassName.js"></script>
    <script>
      myReady(function(){
        var myUl2 = document.getElementById("myUl2");
        var r = getElementsByClassName({
          searchClass: "light dark",
          node: myUl2
        });
        console.log(r[0].innerHTML);
      });
    </script>
  </head>
  <body>
    <ul id="myUl">
      <li class="light">1</li>
      <li class="light dark">2</li>
      <li class="light">3</li>
    </ul>
    <ul id="myUl2">
      <li class="light">1</li>
      <li class="light dark">second</li>
      <li class="light">3</li>
    </ul>
  </body>
</html>

querySelector()和querySelectorAll()方法

querySelectorAll()和querySelector()方法返回的是一個靜態的NodeList,所謂靜態NodeList就是對底層document的更改不會影響到返回的這個NodeList對象.此時返回的NodeList只是querySelectorAll()方法被調用時的文檔狀態的快照

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>querySelector()</title>
    <script src="domReady.js"></script>
    <script>
      myReady(function(){
        var myDiv = document.getElementById('myDiv');
        // querySelector(id)
        var ul = myDiv.querySelector('#myUl');
        var ul = document.querySelector('#myUl');
        // querySelector(css選擇器)
        var li = myDiv.querySelector('li:last-child');
        // querySelector(tag)
        var els = document.querySelector('input, li');
        var span = document.querySelector('span');
        // querySelector(class)
        // class名中有特殊符號須要轉義
        var input = document.querySelector('.foo\\:bar');
        console.log(ul);
        console.log(li);
        console.log(els);
        console.log(span);
        console.log(input);
      });
    </script>
  </head>
  <body>
    <input type="text" class="foo:bar" value="請輸入內容" />
    <div id="myDiv">
      You are my sunshine.
      <ul id="myUl">
        <li>1</li>
        <li>2</li>
        <li>3</li>
      </ul>
    </div>
  </body>
</html>

JS DOM操做-操做節點

document.createTextNode() 建立文本節點

document.createElement() 建立元素節點

document.firstElementChild 第一個子元素節點

appendChild() 在最後追加子節點

.children.item(n) 第n個子元素

insertBefore(pos,null) 在最後追加子節點

li. insertBefore(pos,ul.firstElementChild) 在最前面插入子節點

li. insertBefore(pos,ul.lastElementChild) 在最後追加子節點

replaceChild(新節點,要替換掉的節點)

cloneNode() 克隆節點

cloneNode(true) 克隆節點(包括子節點)

document.body.appendChild(newNode) 克隆以後將新節點添加到文檔中

normalize() 合併某個元素的文本節點

.nodeValue() 獲取節點的值(文本值)

splitText(n) 從n位置進行拆分(拆分元素的文本節點)

 


 

JS DOM操做-刪除節點

 

removeNode() IE方法,刪除指定元素

removeNode(true) IE方法,刪除指定元素及子元素

相關文章
相關標籤/搜索