DOM及DOM查找
1.DOM
【1】定義:專門操作網頁內容的一套對象和函數的總稱
【2】為什么使用DOM:ES標準中只規定了js語言的核心語法,沒有規定如何使用js操作網頁的內容。
【3】何時:今后,只要想操作網頁中的內容,只能用DOM,JQuery和框架都是對DOM的簡化
【3】DOM標準:國際標準,由W3C負責制定并維護,幾乎所有瀏覽器都兼容
2.DOM樹
【1】定義:一個網頁的所有內容是在瀏覽器內存中以樹形結構保存的。
【2】為什么:樹形結構是能夠最直觀的展現上下級包含關系的結構。而網頁內容中的元素結構,也是上下級包含關系
【3】如何創建
? i:只要瀏覽器讀取到一個網頁的內容,都會現在內存中創建一個唯一的樹根節點對象:document
? ii:瀏覽器掃描網頁內容,每掃描到一項內容(元素、文本、屬性…)就會自動創建一個新的節點對象(Node),并保存當前這一項內容的屬性和值,然后將新創建的節點對象保存在DOM樹上對象的位置。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YrLgKhqG-1625900469176)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210710102912635.png)]
3.查找元素
4大類查找方式
3.1不需要查找
不需要查找就可以直接獲得的元素/對象:4個
- 根節點對象:document
- html元素節點對象:document.documentElement
- head元素節點對象:document.head
- body元素節點對象:document.body
3.2按節點間關系查找
【1】定義:按照元素在DOM樹中的上下級或平級關系查找其他元素
【2】何時使用:在已知一個DOM元素對象,想要找這個DOM元素對象周圍附近的元素時,用節點間關系進行查找
【3】如何使用
? i:節點樹
? 1).定義:包含所有網頁內容的完整樹結構
? 2).包含:2大類關系,6個屬性
? ①父子關系:4個屬性
| 獲得一個節點對象的父級節點對象 | 節點對象.parentNode | 返回一個節點對象 |
| 獲得一個節點對象下所有直接子節點對象的集合 | 節點對象.childNodes | 返回類數組對象 |
| 獲得一個對象下的第一個直接子節點對象 | 節點對象.firstChild | 返回一個節點對象 |
| 獲得一個節點對象下的最后一個直接子節點對象 | 節點對象.lastChild | 返回一個節點對象 |
? ②兄弟關系:2個屬性
| 獲得一個節點對象相鄰的前一個兄弟節點對象 | 節點對象.previousSibling | 返回一個節點對象 |
| 獲得一個節點對象相鄰的下一個兄弟節點對象 | 節點對象.nextSibling | 返回一個節點對象 |
? 3).節點樹查找所存在的問題:節點樹會將看不見的回車、空格等空字符也創建為節點對象,嚴重干擾到我們的查找結果!所以,幾乎不用節點樹
? ii:元素樹
? 1).定義:僅包含元素節點的樹形結構
? 2).優點:不會有看不見的空字符的干擾。所以,將來只要按節點間關系朝招元素時,就使用元素樹
? 3).包含:2大類關系,6個屬性
? ①父子關系:4個屬性
| 獲得一個元素對象的父級元素對象 | 元素對象.parentElement | 返回一個元素對象 |
| 獲得一個元素對象下所有直接子元素對象的集合 | 元素對象.children | 返回類數組對象 |
| 獲得一個對象下的第一個直接子元素對象 | 元素對象.firstElementChild | 返回一個元素對象 |
| 獲得一個元素對象下的最后一個直接子元素對象 | 元素對象.lastElementChild | 返回一個元素對象 |
? ②兄弟關系:2個屬性
| 獲得一個元素對象相鄰的前一個兄弟元素對象 | 元素對象.previousElementSibling | 返回一個元素對象 |
| 獲得一個元素對象相鄰的下一個兄弟元素對象 | 元素對象.nextElementSibling | 返回一個元素對象 |
iii:示例
<body><span id="s1">Hello</span><h1>標題一</h1><script>//先獲得四種可直接獲得的節點對象//DOM中: console.log輸出的不是對象存儲結構,而是DOM樹結構(節點間關系)console.log(document);//console.dir(xxx)才是輸出一個節點對象在內存中的屬性結構console.dir(document);console.dir(document.documentElement);console.dir(document.head);console.dir(document.body);//獲得body的第一個直接子元素span// var span=document.body.firstChildvar span=document.body.firstElementChild;console.log(span);//獲得span的下一個兄弟h1// var h1=span.nextSibling;var h1=span.nextElementSibling;console.log(h1);//獲得body下所有直接子元素的集合:3個元素// console.log(document.body.childNodes);console.log(document.body.children);</script> </body>3.3按html特征查找
4個函數
i:按id名查找一個元素
? 1).var 一個元素對象=document.getElementById(“id名”)
? 2).返回值:如果找到符合要求的元素,則只返回一個元素;如果沒找到,則返回null
? 3).強調:.前的主語必須是document,因為只找一個元素,所以函數名中Element沒有s結尾,是單數形式
ii:按標簽名查找多個元素
? 1).var 類數組對象=任意父元素.getElementsByTagName(“標簽名”)
? 2).返回值:如果找到符合要求的元素,就返回類數組對象;如果沒找到,就返回空類數組對象:{length:0}
? 3).注意
? ①因為找到多個元素,所以返回值為類數組對象
? ②最好指定在一個父元素范圍內查找符合要求的元素。——喲花,查找范圍越小,查找越快
? ③因為要查找多個元素,所以函數名中的Elements以s結尾,表示復數
? ④不僅查找直接子元素,而且會在所有后代元素中查找符合要求的元素
? ⑤如果這個函數規定要返回類數組對象,那么在任何時候都會返回類數組對象,即使只找到一個元素,也會把這唯一一個元素放在類數組對象中第一個位置返回。所以,如果只找到一個符合要求的元素時,必須用[0],取出類數組對象中第一個位置保存的元素對象,才能對這個元素對象繼續執行后續操作!
iii:按class名查找多個元素
? 1). var 類數組對象=任意父元素.getElementsByClassName(“class名”)
? 2).返回值:如果找到符合要求的元素,就返回類數組對象;如果沒找到,就返回空類數組對象:{length:0}
? 3).注意
? ①因為找到多個元素,所以返回值為類數組對象
? ②最好指定在一個父元素范圍內查找符合要求的元素。——喲花,查找范圍越小,查找越快
? ③因為要查找多個元素,所以函數名中的Elements以s結尾,表示復數
? ④不僅查找直接子元素,而且會在所有后代元素中查找符合要求的元素
? ⑤如果這個函數規定要返回類數組對象,那么在任何時候都會返回類數組對象,即使只找到一個元素,也會把這唯一一個元素放在類數組對象中第一個位置返回。所以,如果只找到一個符合要求的元素時,必須用[0],取出類數組對象中第一個位置保存的元素對象,才能對這個元素對象繼續執行后續操作!
iv:按name名查找多個表單元素
? 1).var 類數組對象=document.getElementsByName(“name名”)
? 2).返回值:如果找到符合要求的元素,就返回類數組對象;如果沒找到,就返回空類數組對象:{length:0}
? 3).注意
? ①因為找到多個元素,所以返回值為類數組對象
? ②最好指定在一個父元素范圍內查找符合要求的元素。——喲花,查找范圍越小,查找越快
? ③因為要查找多個元素,所以函數名中的Elements以s結尾,表示復數
? ④如果這個函數規定要返回類數組對象,那么在任何時候都會返回類數組對象,即使只找到一個元素,也會把這唯一一個元素放在類數組對象中第一個位置返回。所以,如果只找到一個符合要求的元素時,必須用[0],取出類數組對象中第一個位置保存的元素對象,才能對這個元素對象繼續執行后續操作!
? 4).示例
<body><span>Hello World !</span><ul id="nav"><li class="item parent">電影</li><li class="item parent">綜藝<ul><li class="item child active">向往的生活</li><li class="item child">王牌對王牌</li><li class="item child">青春環游記</li></ul></li><li class="item parent">劇集</li></ul> <form>用戶名:<input name="uname"><br/>性別:<label><input type="radio" name="sex" value="1">男</label><label><input type="radio" name="sex" value="0">女</label></form><script>var ulNav=document.getElementById("nav");console.log(ulNav);var lis=ulNav.getElementsByTagName("li");console.log(lis);lis[2].style.color="orange";var span1=document.getElementsByTagName("span")[0];console.log(span1);span1.style.color="red";var lis1=ulNav.getElementsByClassName("item");console.log(lis1);lis1[3].style.fontSize="30px";//查找name為sex的兩個radio元素var radios=document.getElementsByName("sex");console.log(radios);//查找一個name為uname的元素,為其添加陰影效果var 姓名文本框=document.getElementsByName("uname")[0];console.log(姓名文本框);姓名文本框.style.boxShadow="0 0 5px red";</script></body>3.4按選擇器查找
【1】何時使用:如果元素藏的很深,非常分散時,查找條件變得很復雜,都可用按選擇器查找.
【2】怎樣使用
? i:只查找一個符合要求的元素
var 一個元素對象=任意父元素.querySelector("選擇器")
? ii:查找多個符合要求的元素
var 類數組對象=任意父元素.querySelectorAll("選擇器")
3.5購物車示例
? 【1】所有DOM效果標準的4步:
- 查找所有可能觸發事件的元素
- 綁定事件處理函數
- 查找要修改的元素
- 修改元素
【2】事件綁定
? i:定義:瀏覽器自動觸發的或用戶手動觸發的頁面中內容或狀態的變化
? ii:問題?:默認情況下即使瀏覽器中發生了事件,瀏覽器什么也不會做!因為默認中,各個對象中的時間處理函數為null
? iii:解決:綁定事件處理函數:2種方式
? ①手動在html中元素開始標簽中綁定事件處理函數
`<元素 on事件名="事件處理函數()">``< script >`? function 事件處理函數(){ ... }
缺點:全手工添加,極其不便于維護
? ②在js中綁定
? 1)其實在每個元素對象身上,都有著一批名稱以on開頭的“事件屬性”,比如:onclick, onfocus, onmouseover,…
? 2)當一個元素身上發生了一個事件時,瀏覽器會先在這個元素身上找到對應的事件屬性,并執行事件屬性中保存的事件處理函數
? 3)問題: 開局,所有元素的事件屬性都為null,即使發生事件,也不知道該干什么
? 4). 解決: 事件綁定:
i. 什么是: 提前在元素的某個事件屬性上保存一個function函數。當事件發生時,瀏覽器就可以找到這個函數,并自動執行!
ii. 何時: 只要希望觸發事件時,可以自動執行一項提前定義好的操作時,都要先為元素綁定事件處理函數.
iii. 如何: js中
先找到要觸發事件的元素
元素對象.on事件名=function(){ ... }
? 5). 優點: 自動綁定,可以與for循環配合批量綁定,集中綁定。
【3】示例
<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>var table=document.getElementById("data");var btns=table.getElementsByTagName("button");// console.log(btns);for(var btn of btns){btn.onclick=function(){// 功能一:修改span的內容// 獲取要修改的元素,本次示例中要獲取當前元素button的父對象table的第二個孩子spanvar span=this.parentElement.children[1];// console.log(span);// 獲取span中現在的內容var n=parseInt( span.innerHTML);// 通過單擊按鈕的不同,改變的span中的內容也不同// 如果當前按鈕的內容是+號,就將span中該內容逐次加一if(this.innerHTML=="+"){n++;}else if(n>1){//如果當前按鈕不是+號,且本次按鈕的值不能小于1n--;}span.innerHTML=n;//功能二:更改小計中的內容var tbsub=this.parentElement.nextElementSibling;var price=parseFloat( this.parentElement.previousElementSibling.innerHTML.slice(1));// console.log(price,n);var sub=price*n;// console.log(sub);tbsub.innerHTML=`¥${sub.toFixed(2)}`;// 功能三:小計改變,總計改變// 獲取tfoot中的最后一個總計對象var tftoatl=table.querySelector("tfoot td:last-child");// console.log(tftoatl);// 獲取tbody中的每一行中的最后一個小計var tds=table.querySelectorAll("tbody td:last-child");// 設置一個變量為總計計數做準備var total=0;// 遍歷tbody中的每行中的小計for(var td of tds){// 每行中的小計的值并且截取調¥符號,然后將其轉為數值total +=parseFloat( td.innerHTML.slice(1));}// 將total中計算出的總計的值放入到tfoot中,保留兩位小數tftoatl.innerHTML=`¥${total.toFixed(2)}`;} }</script> </body>總結
- 上一篇: 听说支付宝有一个“疯起来连自己都打”的项
- 下一篇: 线性稳压器和开关稳压器比较