DOM操做

一. 什麼是DOM

1. 什麼是DOM:

Document Object Modelcss

 DOM: 專門操做網頁內容的API的標準——W3Chtml

2.爲何:

爲了統一全部瀏覽器的操做網頁的API標準node

什麼時候: 只要操做網頁的內容,都要用DOM程序員

 包括: 增,刪,改,查,事件綁定正則表達式

3. 查找元素:

 JS=ES(核心語法)+DOM(專門操做網頁內容的API)+BOM(專門操做瀏覽器軟件的API)json

二. DOM Tree

1.什麼是DOM Tree:

內存中保存一個網頁中全部內容的樹形結構數組

 2.爲何:

由於樹形結構是最容易保存複雜的上下級包含關係的結構瀏覽器

 3.如何:

  造成: 瀏覽器在加載一個HTML網頁時,都會建立一棵DOM數。包括:緩存

   惟一的根節點對象: documentapp

   每一個網頁內容(元素、屬性、文字)都會成爲樹上的節點對象

 4.每一個節點對象都有三個屬性:

 1). node.nodeType: 節點類型

 什麼時候: 須要判斷節點類型時可經過節點的值

 值是一個數字:

     document文件     9

     element元素       1

     attribute屬性      2

     text文本          3

 問題: 只能區分節點類型,不能更細緻的區分元素的名稱

 2). node.nodeName: 節點名

     什麼時候: 判斷當前節點的元素名時

     包括:

      document   #document

      element    全大寫的標籤名

      attribute    屬性名

      text        #text

3). node.nodeValue: 節點值——幾乎不用

     包括:

      document   null

      element     null

      attribute    屬性值

      text        文本內容

三.查找元素

1. 不用查找就可直接得到的元素:

4個

  document.documentElement    <html>

  document.head    <head>

  document.body    <body>

  document.forms[i]  <form>

 2. 按節點間關係查找:

 1).什麼時候: 在首先得到了一個元素後,要找周圍附近的元素時

 2). 節點樹: 包含全部節點對象的完整樹結構

      兩大類關係:

   *). 父子關係:

    .parentNode  當前元素的父節點對象

    .childNodes   當前元素的全部直接子節點對象

    .firstChild     當前元素的第一個直接子節點對象

    .lastChild     當前元素的最後一個直接子節點對象

   *). 兄弟關係:

    .previousSibling  當前元素的前一個兄弟節點對象

    .nextSibling      當前元素的下一個兄弟節點對象

   問題: 不但包含元素節點,還受看不見的空字符節點干擾

  3).元素樹: 僅包含元素節點的樹結構

    元素樹不是一棵新樹,而是節點樹中的一個子集而已

   優勢: 只包含元素節點,不包含文本節點,不會受干擾

   包括:

   *).父子關係:

    .parentElement  當前元素的父元素對象

    .children   當前元素的全部直接子元素對象

    .firstElementChild  當前元素的第一個直接子元素對象

    .lastElementChild  當前元素的最後一個直接子元素對象

   *). 兄弟關係:

    .previousElementSibling當前元素的前一個兄弟元素對象

    .nextElementSibling   當前元素的下一個兄弟元素對象

   總結: 從此只要按節點間關係查找元素時,首選元素樹的屬性

  查找一個節點下的全部後代節點:

   兩步:

   *). 先定義函數,僅遍歷直接子元素:

   *). 在函數內,對每一個直接子元素,調用和父元素徹底相同的當前函數自己。

3. 按HTML特徵查找:4種

  1). 按id查找一個元素:

   什麼時候: 當要查找的元素身上有id屬性時,都首選用id查找

   如何: var elem=document.getElementById("id名")

   強調: getElementById只能用document調用

  2). 按標籤名查找多個元素:

   什麼時候: 當元素上沒有id,name,class時,就可用標籤名查找

   如何使用:

    var elems=任意父元素.getElementsByTagName("標籤名")

  3). 按name屬性查找多個元素:

   var elems= document.getElementsByName("name")

   強調:只能在document上調用

  4). 按class屬性查找多個元素:

var elems= parent.getElementsByClassName("class")

強調: *). 可用任意父元素找

        *). 不只查找直接子元素,而是在全部後代中查找符合條件的。

 4. 按選擇器查找

  1).什麼時候: 若是單靠一個條件/特性沒法精確的找到元素時

  2).如何: 2個API:

   *). 只查找一個元素:

    var elem=任意父元素.querySelector("選擇器")

   *). 查找多個元素:

    var elems=任意父元素.querySelectorAll("選擇器")

 

<!DOCTYPE HTML>
<html>
<head>
<title>使用Selector API實現購物車客戶端計算</title>
<meta charset="utf-8" />
<style>
    table{width:600px; text-align:center;
        border-collapse:collapse;
    }
    td,th{border:1px solid black}
    td[colspan="3"]{text-align:right;}
    /*tbody中每行最後一個td背景變爲粉色*/
    table>tbody>tr>td:last-child{
        background:pink
    }
    /*tfoot中最後一個td背景變爲黃色*/
    table>tfoot>tr>td:last-child{
        background:yellow
    }
</style>

</head>
<body>
    <table id="data">
        <thead>
            <tr>
                <th>商品名稱</th>
                <th>單價</th>
                <th>數量</th>
                <th>小計</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>iPhone6</td>
                <td>¥4488.00</td>
        <td>
          <button>-</button>
          <span>1</span>
          <button>+</button>
        </td>
                <td>¥4488.00</td>
            </tr>
            <tr>
                <td>iPhone6 plus</td>
                <td>¥5288.00</td>
                <td>
          <button>-</button>
          <span>1</span>
          <button>+</button>
                </td>
                <td>¥5288.00</td>
            </tr>
            <tr>
                <td>iPad Air 2</td>
                <td>¥4288.00</td>
        <td>
          <button>-</button>
          <span>1</span>
          <button>+</button>
        </td>
                <td>¥4288.00</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3">Total: </td>
                <td>¥14064.00</td>
            </tr>
        </tfoot>
    </table>
<script>
//用id查找table: 查找id爲"data"的元素
var table=document.getElementById("data");
console.log(table);
//用標籤名查找button: 查找table下全部button元素
var buttons=
    table.getElementsByTagName("button");
console.log(buttons);
//事件綁定: 
//事件: 瀏覽器自動觸發的或用戶手動觸發的頁面內容的狀態改變
//事件處理函數: 當事件發生時,自動執行的函數
//事件綁定: 提早將處理函數,賦值給元素的事件屬性,保存住。可是暫不執行。
for(var button of buttons){
    //當單擊按鈕時:爲當前button綁定單擊事件的處理函數
    button.onclick=function(){
        //在事件處理函數中,this可隨時得到單擊的當前按鈕對象
        var btn=this;//先得到當前單擊的按鈕對象
        //1. 修改數量
        //查找btn旁邊的span
        var span=btn.parentNode.children[1];
                   //    td        span
        //得到span中的數字
        var n=parseInt(span.innerHTML);
        //若是btn的內容是+
        if(btn.innerHTML=="+"){
            n++;//就將數字+1
        }else if(n>1){//不然,若是數字>1
            n--;//才能數字-1
        }
        //將數字保存回span的內容中
        span.innerHTML=n;

        //2. 修改小計
        //得到前一個td中的內容中的單價
        var price=parseFloat(
            btn
            .parentNode //td
            .previousElementSibling //前一個td
            .innerHTML //"¥4488.00"
            .slice(1) //"4488.00"
        );//4488
        //計算小計=單價*數量
        var subTotal=price*n;
        //將小計放到後一個td的內容中
        btn.parentNode.nextElementSibling.innerHTML="¥"+subTotal.toFixed(2);

        //3. 修改總計
        //得到tbody中每行最後一個td
        var tds=table.querySelectorAll(
            "tbody>tr>td:last-child"
        );
        console.log(tds);
        //定義變量total=0,準備累加小計
        var total=0;
        for(var td of tds){//遍歷找到的每一個td
            //取出當前td的內容,去掉開頭的¥,轉爲數字,累加到total上
            total+=parseFloat(//4488
                td.innerHTML //"¥4488.00"
                    .slice(1)  //"4488.00"
            )
        }
        //將total保存到tfoot中最後一個td的內容中
        table.querySelector(
            "tfoot>tr>td:last-child"
        )//return 最後一個td
        .innerHTML="¥"+total.toFixed(2)
    }//觸發: 當前按鈕.onclick()
}
</script>
</body>
</html>
shoopingCart

四. 修改:

1.內容:

     三種:

  1). 獲取或修改原始的HTML片斷內容:

   elem.innerHTML

  2). 獲取或修改純文本內容:

   elem.textContent

    比innerHTML多作兩件事:

     *). 翻譯特殊符號爲正文

     *). 去掉內嵌的子標籤,只保留文字

  3). 表單元素的值:

   elem.value

<!DOCTYPE HTML>
<html>
<head>
<title>讀取並修改元素的內容</title>
<meta charset="utf-8" />
<style>
    div{float:left; height: 100px; line-height: 100px; }
    #d1,#d3{ background-color: #ccff00; }
    #d2{ cursor: pointer; background-color: #ffcc00; }
</style>
</head>
<body>
    <div id="d1">樹形列表</div>
    <div id="d2">&lt;&lt;</div>
    <div id="d3">內容的主體</div>
<script>
//1. 查找觸發事件的元素: 
var d2=document.getElementById("d2");
//2. 綁定事件處理函數
d2.onclick=function(){
    var d2=this;//得到當前單擊的d2
    //3. 查找要修改的元素:
    var d1=document.getElementById("d1");
    //4. 修改元素:控制d1的顯示或隱藏
    //若是當前d2的內容是<<
    //if(d2.innerHTML=="&lt;&lt;"){
    if(d2.textContent=="<<"){
        //<div id="d1" style="display:none">
        d1.style.display="none";
        //修改當前d2的內容爲>>
        //d2.innerHTML="&gt;&gt;";
        d2.textContent=">>";
    }else{//不然
        d1.style.display="block";
        d2.textContent="<<";
    }
}
</script>
</body>
</html>
door

 2.屬性:

  三種:

  1). HTML標準屬性: 2種:

   *). 核心DOM API: 4個
     獲取屬性值: var value=elem.getAttribute("屬性名")

     修改屬性值: elem.setAttribute("屬性名","新值")

     移除屬性: elem.removeAttribute("屬性名")

     判斷是否包含屬性: var bool=elem.hasAttribute("屬性名")

   *). HTML DOM API: 對經常使用核心DOM API的簡化

     HTML DOM提早將全部HTML標準屬性,定義在內存中的元素對象上:

      elem.屬性名

      特例: class是ES標準中的關鍵字

           DOM中不容許再使用class做爲屬性名

           class一概都要改成className

           DOM中的className屬性等於HTML中的class

<!DOCTYPE HTML>
<html>
<head>
<title>1. 實現伸縮二級菜單</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/1.css" />

</head>
<body>
    <ul class="tree">
        <li>
            <span class="open">考勤管理</span>
            <ul>
                <li>平常考勤</li>
                <li>請假申請</li>
                <li>加班/出差</li>
            </ul>
        </li>
        <li>
            <span>信息中心</span>
            <ul>
                <li>通知公告</li>
                <li>公司新聞</li>
                <li>規章制度</li>
            </ul>
        </li>
        <li>
            <span>協同辦公</span>
            <ul>
                <li>公文流轉</li>
                <li>文件中心</li>
                <li>內部郵件</li>
                <li>即時通訊</li>
                <li>短信提醒</li>
            </ul>
        </li>
    </ul>
<script>
//1. 查找觸發事件的元素
//查找class爲tree的ul下的li下的全部span
var spans=document.querySelectorAll(
    "ul.tree>li>span"
);
console.log(spans);
//2. 綁定事件處理函數
for(var span of spans){//遍歷每一個span
    //爲每一個span綁定單擊事件處理函數
    span.onclick=function(){
        var span=this;//得到當前單擊的span
        //3. 查找要修改的元素
        //4. 修改元素
        //若是當前span本身是開着的
        if(span.className=="open"){
            span.className="";//只要把本身關閉便可
        }else{//不然(若是本身是關着的)
            //查找其它可能開着的span: 
            //class爲tree的ul下的class爲open的span
            var openSpan=document.querySelector(
                "ul.tree>li>span.open"
            );
            if(openSpan!=null){//若是找到
                //就將其它開着的span關閉
                openSpan.className="";
            }
            //而後才把當前span本身打開
            span.className="open";
        }
    }
}
</script>
</body>
</html>
menu

  2). 狀態屬性: enabled  disabled  selected  checked

   值都是bool類型,不是字符串類型,不能用核心DOM API修改。

   只能用HTML DOM的.來訪問

   補充: CSS3中有一種特殊的選擇器: 狀態僞類:

    :enabled    :disabled   :checked   :selected

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>全選和取消全選</title>
</head>
<body>
    <h2>管理員列表</h2>
    <table border="1px" width="500px">
      <thead>
        <tr>
            <th><input type="checkbox"/>全選</th>
            <th>管理員ID</th>
            <th>姓名</th>
            <th>操做</th>
        </tr>
      </thead>
      <tbody>
          <tr>
              <td><input type="checkbox"/></td>
              <td>1</td>
              <td>Tester</td>
              <td>修改 刪除</td>
          </tr>
          <tr>
              <td><input type="checkbox"/></td>
              <td>2</td>
              <td>Manager</td>
              <td>修改 刪除</td>
          </tr>
          <tr>
              <td><input type="checkbox"/></td>
              <td>3</td>
              <td>Analyst</td>
              <td>修改 刪除</td>
          </tr>
          <tr>
              <td><input type="checkbox"/></td>
              <td>4</td>
              <td>Admin</td>
              <td>修改 刪除</td>
          </tr>
      </tbody>
    </table>
    <button>刪除選定</button>
<script>
//1. 查找觸發事件的元素: table下thead下的input
var chbAll=document.querySelector(
    "table>thead input"
);
//2. 綁定事件處理函數
chbAll.onclick=function(){
    var chbAll=this;//得到當前單擊的chbAll對象
    //3. 查找要修改的元素:tbody下每行第一個td中的input
    var chbs=document.querySelectorAll(
        "table>tbody>tr>td:first-child>input"
    );
    console.log(chbs);
    //4. 修改元素
    for(var chb of chbs){//遍歷每一個chb
        //修改當前chb的checked屬性的值爲chbAll的checked屬性值
        chb.checked=chbAll.checked;
    }
}

//1. 查找觸發事件的元素
//查找table下tbody下每行第一個td中的input,保存在chbs中
var chbs=document.querySelectorAll(
    "table>tbody>tr>td:first-child>input"
);
//2. 綁定事件處理函數
for(var chb of chbs){//遍歷chbs中每一個chb
    //爲當前chb綁定單擊事件處理函數
    chb.onclick=function(){
        //3. 查找要修改的元素
        //查找table下thead下的input
        var chbAll=document.querySelector(
            "table>thead input"
        );
        //4. 修改元素
        var chb=this;//得到當前單擊的chb對象
        //若是當前chb是取消選中的
        if(chb.checked==false){
            chbAll.checked=false;
        }else{//不然(若是當前chb被選中)
            //嘗試查找tbody中每行第一個td中「未選中」的input
            var unchecked=document.querySelector(
                "table>tbody>tr>td:first-child>input:not(:checked)"
            );
            //若是沒找到(說明都選中了)
            if(unchecked==null){
                chbAll.checked=true;
            }
        }
    }
}
</script>
</body>
</html>
selectAll

 

  3). 自定義擴展屬性:

 什麼是: HTML標準中沒有規定的,程序員自行添加的屬性

 什麼時候: 2種:

    *). 用自定義擴展屬性做爲條件,選擇要綁定事件的元素

     爲何不用id,class,元素 選擇器

       id只能選擇一個元素

       class是定義樣式用的,常常變化

       元素選擇器限制太死。實現一種效果,可能用不一樣的元素都行。

     使用自定義擴展屬性做爲條件綁定事件的好處:

      不受個數,樣式,元素名的干擾!

    *). 在客戶端元素上臨時緩存業務數據

     爲何: 避免重複請求服務端,形成延遲

 定義自定義擴展屬性:

    <ANY 自定義屬性名="值">

    HTML5標準中: <ANY  data-自定義屬性名="值"

   獲取或修改自定義擴展屬性:

    *). 核心DOM API:

      .getAttribute()

      .setAttribute()

      .removeAttribute()

      .hasAttribute()

      強調: HTML DOM API不能操做自定義擴展屬性

          由於自定義擴展屬性是後天自定義的,HTML標準中沒有。因此不包含在元素對象中。因此不能用.直接訪問。

    *). HTML5標準中:

      elem.dataset //可自動得到全部data-*開頭的屬性

          .自定義屬性名  //使用dataset訪問自定義屬性時,不用data-前綴

 

 

<!DOCTYPE HTML>
<html>
<head>
<title>讀取並修改元素的屬性</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/3.css" />
<style></style>

</head>
<body>
    <h2>實現多標籤頁效果</h2>
  <div class="tabs">
    <ul id="tab">
      <li><a href="#" data-target="content1" data-toggle="tab">10元套餐</a></li>
      <li><a href="#" data-target="content2" data-toggle="tab">30元套餐</a></li>
      <li><a href="#" data-target="content3" data-toggle="tab">50元包月</a></li>
    </ul>
    <div id="container">
      <div id="content1">
        10元套餐詳情:<br />&nbsp;每個月套餐內撥打100分鐘,超出部分2毛/分鐘
      </div>
      <div id="content2">
        30元套餐詳情:<br />&nbsp;每個月套餐內撥打300分鐘,超出部分1.5毛/分鐘
      </div>
      <div id="content3">
        50元包月詳情:<br />&nbsp;每個月無限量隨心打
      </div>
    </div>
  </div>
<script>
//起始時,默認顯示第一個div的內容
document.getElementById("content1")
        .style.zIndex=9;
//1. 查找觸發事件的元素
var tabs=document.querySelectorAll(
  "[data-toggle=tab]"
);
console.log(tabs);
var n=10;//用來遞增z-index的值
//2. 綁定事件處理函數
for(var tab of tabs){
  tab.onclick=function(){
    var tab=this;
    //3. 查找要修改的元素
    //先獲取保存在當前tab上的目標div的id
    var id=tab.getAttribute("data-target");
         //tab.dataset.target;
    //再用id查找對應的div
    var content=document.getElementById(id);
    //4. 修改元素
    //<div style="z-index:10"
    //全部帶-的css屬性,都要去-變駝峯
    content.style.zIndex=n;
    n++;
  }
}
</script>
</body>
</html>
tabs

3.樣式:

1).修改內聯樣式:

   elem.style.css屬性名="值"

   等效於: <ELEM style=" css屬性名:值"

   強調: *). css屬性名中若是帶-,須要去橫線變駝峯:

          z-index  =>   zIndex

          list-style  =>  listStyle

          background-color => backgroundColor

        *). 若是是帶單位的數字屬性:

          修改時: 必須手動拼接單位到結尾:

           .style.width=12+"px";

          獲取時: 必須去掉結尾的px,才能作計算

          好比: width="12.5px"

           parseFloat(width) => 12.5

   問題: elem.style 僅表明內聯樣式:

     修改時,若是elem.style,優先級最高!

     獲取時,只能獲取內聯樣式,沒法獲取外部樣式表中的樣式。

   獲取樣式: 不能用style

   應該獲取計算後的樣式: 最終應用到元素上的全部樣式的集合。

   如何: 2步:

    *). 先得到計算後的樣式的集合對象:

         var style=getComputedStyle(elem)

    *). 獲取一個css屬性的值:

         style.css屬性

   強調: 由於計算後的樣式屬性來源不肯定,因此都是隻讀的。

 

 問題: elem.style修改樣式,一句話只能修改一個css屬性

      若是同時修改多個css屬性,代碼會很繁瑣

 解決: 從此,只要批量修改css屬性,都要首選class方式修改

  

 

<!doctype html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>實現帶樣式的表單驗證</title>
    <link rel="Stylesheet" href="css/5.css" />
 </head>
 <body>
    <form id="form1">
        <h2>增長管理員</h2>
        <table>
            <tr>
                <td>姓名:</td>
        <td>
                    <input name="username"/>
                    <span>*</span>
                </td>
                <td>
                    <div class="vali_info">
                        10個字符之內的字母、數字或下劃線的組合
                    </div>
                </td>
            </tr>
            <tr>
                <td>密碼:</td>
                <td>
                    <input type="password" name="pwd"/>
                    <span>*</span>
                </td>
                <td>
                    <div class="vali_info">6位數字</div>
                </td>
            </tr>
            <tr>
                <td></td>
                <td colspan="2">
          <input type="submit" value="保存"/>
          <input type="reset" value="重填"/>
                </td>
            </tr>                
        </table>
    </form>
<script>
//當文本框得到焦點時
    //給當前文本框本身穿"txt_focus"讓邊框變粗
    //找到當前文本框旁邊的div,清除其class
//1. 查找觸發事件的元素
//分別查找name爲username和pwd的兩個文本框
var txtName=
    document.getElementsByName("username")[0];
    //[input][0]
var txtPwd=
    document.getElementsByName("pwd")[0];
//2. 綁定事件處理函數
//var a; var b;  a=b=3;
txtName.onfocus=txtPwd.onfocus=function(){
    //3. 查找要修改的元素
    var txt=this;//得到當前文本框本身
    var div=//找到旁邊的div
        txt.parentNode //td
                .nextElementSibling //下一個td
                .children[0];  //div
    //4. 修改元素
    txt.className="txt_focus";
    div.className="";
}


//當文本框失去焦點時
    //清除當前文本框的class,讓邊框恢復正常
    //定義正則表達式
    //驗證當前文本的內容
    //若是驗證經過
        //就給當前文本框旁邊的div穿"vali_success"
    //不然
        //就給當前文本框旁邊的div穿"vali_fail"
//1. 查找觸發事件的元素
//2. 綁定事件處理函數
txtName.onblur=function(){
    vali(this,/^\w{1,10}$/);
}
function vali(txt,reg){
    //3. 查找要修改的元素
    var div=//找到旁邊的div
        txt.parentNode //td
                .nextElementSibling //下一個td
                .children[0];  //div
    //4. 修改元素
    txt.className="";
    //若是驗證經過
    if(reg.test(txt.value)==true){
        div.className="vali_success";
    }else{//不然
        div.className="vali_fail";
    }
}
txtPwd.onblur=function(){
    vali(this,/^\d{6}$/);
}
</script>
 </body>
</html>
vailWIthCSS

四. 添加/刪除

 1.添加:

1).3步:

  *). 建立一個空元素對象

    var a=document.createElement("a")

    a: <a></a>

  *). 設置關鍵屬性

    a.href="http://tmooc.cn";

    a.innerHTML="go to tmooc";

    a: <a href="http://tmooc.cn"> go to tmooc </a>

  *). 將新對象掛載到DOM樹上指定位置

    3種:

    a). 在當前父元素下的結尾,追加一個新元素:

      父元素.appendChild(a)

    b). 在父元素下的某個子元素以前插入:

      父元素.insertBefore(a, child)

    c). 替換父元素的某個子元素:

      父元素.replaceChild(a, child)

 

 

2).優化: 儘可能減小修改DOM樹的次數

   由於每修改一次DOM樹,瀏覽器都會重繪頁面

   頁面加載過程:

    html -> DOM樹

            ↓

           加載樹 -> 排版 -> 繪製

            ↑       很是耗時

    css -> COM模型

    每次修改DOM樹都會致使重排重繪

<!DOCTYPE HTML>
<html>
<head>
<title>動態建立表格</title>
<meta charset="utf-8" />
<style>
    table{width:600px; border-collapse:collapse;
        text-align:center;
    }
    td,th{border:1px solid #ccc}
</style>

</head>
<body>
<div id="data">
<!--
  <table>//建立table元素,並追加到div#data下
    <thead>//建立thead元素,並追加到table下
      <tr>//建立tr元素,並追加到thead下
        //遍歷json數組中第一個對象的每一個屬性
        //for(var key in json[0])
          //建立<th>並追加到<tr>下
          //設置<th>的內容爲key
        <th>ename</th>
        <th>salary</th>
        <th>age</th>
      </tr>
    </thead>
    <tbody>//建立tbody,並追加到table下
      //遍歷json中每一個員工對象
        //每遍歷一個對象就建立一個tr追加到tbody下
        <tr>
        //遍歷當前員工對象的每一個屬性
          //每遍歷一個屬性就建立一個td並追加到tr下,並設置td的內容爲當前屬性的值
          <td>Tom</td>
          <td>11000</td>
          <td>25</td>
        </tr>
    </tbody>
  </table>-->
</div>
<script>//day03/2_createTable_HTMLDOM.html
var json=[
  {"ename":"Tom", "salary":11000, "age":25},
  {"ename":"John", "salary":13000, "age":28},
  {"ename":"Mary", "salary":12000, "age":25}
];
//建立table元素
var table=document.createElement("table");

//建立thead元素,並追加到table下
var thead=document.createElement("thead");
table.appendChild(thead);
//建立tr元素,並追加到thead下
var tr=document.createElement("tr");
thead.appendChild(tr);
//遍歷json數組中第一個對象的每一個屬性
for(var key in json[0]){
  //建立<th>並追加到<tr>下
  var th=document.createElement("th");
  tr.appendChild(th);
  th.innerHTML=key;//設置<th>的內容爲key
}

//建立tbody,並追加到table下
var tbody=document.createElement("tbody");
table.appendChild(tbody);
for(var emp of json){//遍歷json中每一個員工對象
  //每遍歷一個對象就建立一個tr追加到tbody下
  var tr=document.createElement("tr");
  tbody.appendChild(tr);
  //遍歷當前員工對象的每一個屬性
  for(var key in emp){
    //每遍歷一個屬性就建立一個td並追加到tr下,並設置td的內容爲當前屬性的值
    var td=document.createElement("td");
    tr.appendChild(td);
    td.innerHTML=emp[key];//當前屬性的值
               //emp["key"];
               //emp.key;
  }
}

//最後,再將整個table一次性追加到div#data下
document.getElementById("data")
        .appendChild(table);
</script>
</body>
</html>
createTable.HTMLDOM

   3).如何: 2種:

    *). 若是同時添加父元素和子元素時,應該先在內存中將子元素添加到父元素中,最後再一次性將父元素添加到DOM樹

    *). 若是父元素已經在頁面上了,要同時添加多個平級子元素時。先將多個子元素臨時加入文檔片斷對象中。再一次性將文檔片斷對象添加到DOM樹上。

     文檔片斷對象將子元素送到DOM樹後,自動釋放不佔頁面空間 。

     文檔片斷: 內存中,臨時保存多個平級子元素的,虛擬的父元素。

      什麼時候: 同時添加多個平級子元素到DOM樹時

      如何:

       a). 先建立一個文檔片斷對象:

         var frag=document.createDocumentFragment();

       b). 將子元素添加到frag中

         frag.appendChild(child)

       c). 將frag總體添加到DOM樹

         父元素.appendChild(frag)

4). 刪除:

 父元素.removeChild(child)

<!DOCTYPE HTML>
<html>
<head>
<title>二級聯動列表</title>
<meta charset="utf-8" />
<style>
    .hide{ display: none; }
</style>


</head>
<body>
    <select name="provs">
        <option>—請選擇—</option><!--0-->
        <option value="bj">北京市</option><!--1-->
        <option value="tj">天津市</option>
        <option value="hb">河北省</option>
    </select>
    <select name="cities" class="hide">
    </select>
<script>
/*實現「省」和「市」的級聯下拉列表*/
var cities=[
  [
    {"name":'東城區',"value":101},
    {"name":'西城區',"value":102},
    {"name":'海淀區',"value":103},
    {"name":'朝陽區',"value":104}
  ],
  [
    {"name":'河東區',"value":201},
    {"name":'河西區',"value":202},
    {"name":'南開區',"value":203}
  ],
  [
    {"name":'石家莊市',"value":301},
    {"name":'廊坊市',"value":302},
    {"name":'保定市',"value":303},
    {"name":'唐山市',"value":304},
    {"name":'秦皇島市',"value":305}
  ]
];
//1. 查找觸發事件的元素
var selProvs=
  document.getElementsByName("provs")[0];
//2. 綁定事件處理函數
//當selProvs中的選中項改變時自動執行
selProvs.onchange=function(){
  //alert(this.value);
  //3. 查找要修改的元素:第二個select
  var selCts=
      document.getElementsByName("cities")[0]
  //4. 修改元素
  var selProvs=this;
  var i=selProvs.selectedIndex;
  if(i>0){
    var cts=cities[i-1];
    var frag=
      document.createDocumentFragment();
    //先添加一個<option>-請選擇-
    /*var opt=document.createElement("option");
    opt.innerHTML="-請選擇-";*/
    frag.appendChild(new Option("-請選擇-"));
    for(var city of cts){
      //每遍歷一個城市,就建立一個option,並加入frag中
      /*var opt=document.createElement("option");
      frag.appendChild(opt);
      //將當前城市對象的name放入option中
      opt.innerHTML=city.name;*/
      frag.appendChild(new Option(city.name))
    }
    //每次添加新option以前,先清除舊的內容
    selCts.innerHTML="";
    selCts.appendChild(frag);
    selCts.className="";
  }else{
    selCts.className="hide";
  }
}
</script>
</body>
</html>
級聯下拉列表

五. HTML DOM經常使用對象:

 Image  Select/option   Table/...    Form/...

1. Image:

var img=new Image();

2.Select對象:

表明頁面上一個<select>

  1).屬性: .selectedIndex 快速得到當前選中項的位置

       .options 快速得到select下全部option的集合

         .options.length  得到select下option的個數

       .length => .options.length

       .value 得到select中當前選中項的值

            若是選中項沒有value,則用內容做爲value

  2).方法: .add(option) 向select中添加一個option

         問題: 不支持文檔片斷

       .remove(i)  移除select中i位置的option

3.Option對象:

表明select中每一個option元素

   1).建立: var opt=new Option(text,value)

 

 

 

 4.Table對象:

表明頁面上一個<table>元素

  1).管着行分組:

   添加行分組: var thead=table.createTHead()

              var tbody=table.createTBody()

              var tfoot=table.createTFoot()

 

 

   2).刪除行分組: table.deleteTHead()

              table.deleteTFoot()

   3).獲取行分組: table.tHead

              table.tFoot

              table.tBodies[i]

  4).行分組管着行:

   添加行: var tr=行分組.insertRow(i)

          在當前行分組中i位置,插入一個新行

          固定用法:

           *). 行分組.insertRow(0) 開頭插入

           *). 行分組.insertRow() 末尾追加

   刪除行: 行分組.deleteRow(i)

          刪除行分組內的i位置的行

          強調: i是相對於行分組內的下標

          問題: 行分組內的下標位置沒法自動得到

          解決: 從此只要刪除行,都用:

           table.deleteRow(tr.rowIndex)

           其中: tr.rowIndex可得到tr在整個表中的下標位置

   獲取行: 行分組.rows[i] 得到當前行分組中的第i行

<!DOCTYPE HTML>
<html>
<head>
<title>動態建立表格</title>
<meta charset="utf-8" />
<style>
    table{width:600px; border-collapse:collapse;
        text-align:center;
    }
  td,th{border:1px solid #ccc}
  
  table>thead td{font-weight:bold}
</style>

</head>
<body>
<div id="data"></div>
<script>
var json=[
  {"ename":"Tom", "salary":11000, "age":25},
  {"ename":"John", "salary":13000, "age":28},
  {"ename":"Mary", "salary":12000, "age":25}
];
//建立table元素
var table=document.createElement("table");

//建立thead元素,並追加到table下
var thead=table.createTHead();
//建立tr元素,並追加到thead下
var tr=thead.insertRow();
//遍歷json數組中第一個對象的每一個屬性
for(var key in json[0]){
  //建立<th>並追加到<tr>下
  tr.insertCell().innerHTML=key;
}
//新建一個th
tr.insertCell().innerHTML="刪除";

//建立tbody,並追加到table下
var tbody=table.createTBody();
for(var emp of json){//遍歷json中每一個員工對象
  //每遍歷一個對象就建立一個tr追加到tbody下
  var tr=tbody.insertRow();
  //遍歷當前員工對象的每一個屬性
  for(var key in emp){
    //每遍歷一個屬性就建立一個td並追加到tr下,並設置td的內容爲當前屬性的值
    tr.insertCell().innerHTML=emp[key];
  }
  //建立一個新的td
  var td=tr.insertCell();
  td.innerHTML=`<button>×</button>`;
  //查找td下惟一一個元素,並綁定單擊事件處理函數
  td.children[0].onclick=function(){
    //得到當前按鈕:
    var btn=this;
    //得到當前按鈕所在的行
    var tr=btn.parentNode.parentNode;
                //td        //tr
    var ename=tr.cells[0].innerHTML;
            //   第一個td   的  內容
    //若是確認刪除
    if(confirm(`是否繼續刪除 ${ename}?`)){
      //刪除當前按鈕所在的行
      table.deleteRow(tr.rowIndex);
    }
  }
}

//最後,再將整個table一次性追加到div#data下
document.getElementById("data")
        .appendChild(table);
</script>
</body>
</html>
createTable.HTMLDOM

  5).行管着格:

   添加格: var td=tr.insertCell(i)

          固定用法: tr.insertCell() 在行末尾追加新格

          問題: 只能建立td,不能建立th

   刪除格: tr.deleteCell(i)

   獲取格: tr.cells[i]

5.Form對象:

   表明頁面上一個表單元素

  1).獲取: var form=document.forms[i];

  2).屬性: .elements 可得到表單中全部表單元素的集合

        .elements.length 得到表單中全部表單元素的個數

       .length => .elements.length

  3).方法: form.submit() 手動調用程序控制提交表單

  4).表單元素:

   獲取: .elements[i/id/name]

         若是表單元素上有name屬性(好比input表單元素有name屬性值):

           form.name屬性值

   方法: elem.focus() 讓當前表單元素得到焦點

        elem.blur()  讓當前表單元素失去焦點

 

5).onsubmit

在最終提交表單以前觸發

//Step1:爲name爲username和pwd的文本框綁定得到焦點事件
var form=document.forms[0];
//var txtName=form.elements["username"];
var txtName=form.username;
var txtPwd=form.pwd;
txtName.onfocus=getFocus;
txtPwd.onfocus=getFocus;
function getFocus(){
  //this->當前文本框
  //當前文本框邊框加粗
  this.className="txt_focus";
  //清除旁邊div的class
  var div=this.parentNode
      .nextElementSibling
      .firstElementChild;
  div.className="";
}
txtName.onblur=function(){
  vali(this,/^\w{1,10}$/);
}
function vali(txt,reg){
  //清除當前文本框的class
  txt.className="";
  //獲取旁邊div
  var div=txt.parentNode
    .nextElementSibling
    .firstElementChild;
  //用reg測試當前文本框的內容
  //若是經過,就修改div的class爲vali_success
  if(reg.test(txt.value)){
    div.className="vali_success";
    return true;
  }else{//不然修改div的class爲vali_fail
    div.className="vali_fail";
    return false;
  }
}
txtPwd.onblur=function(){
  vali(this,/^\d{6}$/);
}
//找到倒數第2個保存按鈕,並綁定單擊事件
form.elements[form.length-2].onclick=function(){
  /*//驗證每一個文本框
  var rname=vali(txtName,/^\w{1,10}$/);
  var rpwd=vali(txtPwd,/^\d{6}$/);
  //只有都驗證經過
  if(rname==true&&rpwd==true){
    form.submit();//才提交表單
  }*/
  //若是驗證姓名文本框未經過
  if(vali(txtName,/^\w{1,10}$/)==false){
    txtName.focus();//讓姓名文本框得到焦點
  }else if(vali(txtPwd,/^\d{6}$/)==false){//不然若是驗證密碼框未經過
    txtPwd.focus();//讓密碼框得到焦點
  }else{//不然
    form.submit();//才提交表單
  }
}
驗證文本框
相關文章
相關標籤/搜索