一. 什麼是DOM |
1. 什麼是DOM:Document Object Modelcss DOM: 專門操做網頁內容的API的標準——W3Chtml 2.爲何:爲了統一全部瀏覽器的操做網頁的API標準node 什麼時候: 只要操做網頁的內容,都要用DOM程序員 包括: 增,刪,改,查,事件綁定正則表達式 3. 查找元素:JS=ES(核心語法)+DOM(專門操做網頁內容的API)+BOM(專門操做瀏覽器軟件的API)json |
二. DOM Tree1.什麼是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> |
四. 修改: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"><<</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=="<<"){ if(d2.textContent=="<<"){ //<div id="d1" style="display:none"> d1.style.display="none"; //修改當前d2的內容爲>> //d2.innerHTML=">>"; d2.textContent=">>"; }else{//不然 d1.style.display="block"; d2.textContent="<<"; } } </script> </body> </html> 2.屬性:三種: 1). HTML標準屬性: 2種: *). 核心DOM API: 4個 修改屬性值: 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> 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>
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 /> 每個月套餐內撥打100分鐘,超出部分2毛/分鐘 </div> <div id="content2"> 30元套餐詳情:<br /> 每個月套餐內撥打300分鐘,超出部分1.5毛/分鐘 </div> <div id="content3"> 50元包月詳情:<br /> 每個月無限量隨心打 </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> 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> 四. 添加/刪除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> 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> 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();//才提交表單 } } |