JavaScript DOM API的使用教程及綜合案例
一. 什麼是DOM
JavaScript主要由ECMAScript
, DOM
, BOM
這三部分組成; 我們要知道要完成一個程序, 光有語法是遠遠不夠的, 對於JS來說, 除JS語法(ES)外, 還需要掌握一些WebAPI, 這些API是瀏覽器給JS代碼提供的功能, 即DOM和BOM; DOM是頁面文檔對象模型, 可以對頁面中的元素進行操作, 而BOM是瀏覽器對象模型, 可以對瀏覽器窗口進行操作; 本篇博客中主要介紹的就是DOM
.
DOM 全稱為 Document Object Model, 是頁面文檔對象模型, html中的每個標簽都是可以映射到JS中的一個對象中的, 標簽中的內容都可以通過JS對象感知到, JS對象修改對應的屬性能夠影響到標簽的展示, 通過這樣的DOM API就可以讓JS代碼來操作頁面元素.
二. 最常用的DOM API
1. 選中頁面元素
在DOM中, 任何一個頁面, 都會有一個document
對象, 是頁面的一個全局對象, 所有的DOM API都是通過document
對象類展開的, 其中document對象中的querySelector
和querySelectorAll
函數可以用來選擇元素, 通過傳入CSS選擇器來達到目的, 選擇的范圍是位於該函數之前所存在的選擇器, 沒找到返回值為null
.
let obj = document.querySelector('選擇器');
要註意使用querySelector
函數如果符合選擇的標簽在頁面中有多個, 就隻會選擇在頁面中第一次出現的標簽.
如果想把符合選擇的元素都選中就需要使用querySelectorAll
函數瞭, 在使用上和和querySelector 是一樣的.
let elem = document.querySelectorAll('選擇器');
使用該函數會返回一個類似於數組的對象, 用法和數組相同.
將得到的數組對象裡面的元素展開查看, 會發現有很多的屬性, 這些屬性都是DOM原生的一些屬性.
2. 操作元素的屬性
2.1 事件概念
JS要構建動態頁面, 就需要感知到用戶的行為, 而 “事件” 就是針對用戶的操作進行的一些響應, 比如鼠標點擊, 鼠標移動, 鍵盤輸入, 調整瀏覽器窗口這些都是用戶的操作, 而代碼就需要根據這些事件做出相應的響應.
事件的三要素:
- 事件源, 哪個HTML元素產生的事件.
- 事件類型, 比如鼠標點擊, 鼠標移動, 鍵盤輸入等.
- 事件處理程序, 當事件發生之後, 要執行哪個代碼.
前端頁面中, 針對不同的事件也是有不同的處理方式的, 而處理方式都是再最開始的時候就設定好的(事件綁定).
看下面的這一行代碼就是直接在元素標簽中使用onXXX
這樣的屬性來綁定一個事件處理程序, onclick
是一個描述處理鼠標點擊的事件.
<button onclick="alert('hello')">點一下試試</button>
如果事件處理的代碼比較多的話使用上面這種寫法就不太合適瞭, 所以更推薦的是下面這種寫法, 可以直接使用onXXX
這樣的方法進行綁定, 效果和上面是一樣的.
<script !src=""> let button = document.querySelector("button"); button.onclick = function (){ alert("hello"); } </script> <button onclick="alert('hello')">點一下試試</button>
當然,這裡的JS代碼如果是寫在一個單獨的JS文件中就更好瞭, 但本篇中的示范代碼都比較簡單, 就使用內嵌式的寫法來引入JS代碼瞭.
2.2 獲取/修改元素內容
在選中元素後, 就可以使用innerHTML
屬性來獲取/修改一個標簽裡面的內容瞭.
//1.選中標簽 let var_name = document.querySelector(); //2.獲取內容 let content = var_name.innnerHTML; //3.修改內容 var_name.innerHTML = '修改值';
代碼示例, 將點擊按鈕和輸出div
中的內容綁定.
<div> hello world</div> <button>點一下試試</button>--> <script> let but = document.querySelector('but'); but.onclick = function () { let div = document.querySelector('div'); console.log(div.innerHTML); } </script>
觀察控制臺的結果, 控制臺中多次點擊按鈕的結果都被折疊輸出瞭, 這是因為chrome控制臺會默認把相鄰且相同的日志進行合並, 另外再顯示一個數字表示輸出的次數, 我們可以點擊開發者工具的設置欄, 設置一下讓它不合並就行瞭.
還要註意的是, 通過innerHTML
是可以獲取到div內部的html結構的, 比如下面的的代碼, 會將div標簽中的html代碼也獲取到, 而innerText
隻能獲取文本內容, 並不能獲取html結構, innerHTML用的場景是要比innerText更多的.
<div> <span>hello world</span> <span>hello world</span> </div> <button class="but">點一下試試</button> <script> let but = document.querySelector('.but'); but.onclick = function () { let div = document.querySelector('div'); console.log(div.innerHTML); } </script>
修改元素也是一樣的操作, 比如將上面代碼中的div
中的內容修改為一個標題.
<div> <span>hello world</span> <span>hello world</span> </div> <button class="but">點一下試試</button> <script> let but = document.querySelector('.but'); but.onclick = function () { let div = document.querySelector('div'); div.innerHTML = '<h1>這是一個一級標題</h1>>'; console.log(div.innerHTML) } </script>
計數器
有瞭上面的獲取和修改元素的知識, 我們這裡實現一個簡單的計數器, 就是點擊一下按鈕, 計數器就+1
.
實現思路也很簡單, 用戶的點擊操作, 就會觸發點擊事件, 就是先獲取到計數元素中的內容, 然後將元素內容進行加一操作再寫回元素中, 代碼如下:
<div id='count'>0</div> <button id='countAdd'>計數器:點擊+1</button> <script !src=""> let counterAdd = document.querySelector('#countAdd'); counterAdd.onclick = function () { let num = document.querySelector('#count'); numAdd = parseInt(num.innerHTML) + 1 num.innerHTML = numAdd; }; </script>
這個代碼要註意的是, num.innerHTML
這裡拿到的元素內容是字符串類型的, 直接進行加法運算就是字符串拼接的效果瞭, 而要完成算數相加的效果就需要將字符串轉換為整數, 和Java中類似, 可以使用parseInt
方法將字符串轉換為整數, 而如果是浮點數就使用parseFloat
方法
2.4 獲取/修改元素屬性
點擊圖片切換
上面介紹的是修改元素(標簽)中的內容, 我們還可以在代碼中使用DOM直接獲取元素的屬性並修改元素的屬性, 比如這裡實現一個效果, 就是點擊一個圖片就可以切換到另一張圖片, 然後再點擊就能再切換回來, 這個案例我們隻需要設置點擊事件為修改圖片的路徑即可, 也就是修改src
屬性.
代碼如下:
這裡要註意圖片的路徑盡量不要設置成中文的, 中文路徑在瀏覽器中涉及轉義重新編碼的問題, 轉義後路徑就可能沒有中文字符瞭, 判斷就可能出問題瞭.
<style> img { height: 500px; } </style> <img src="./man.jpg" alt=""> <script !src> let img = document.querySelector("img"); console.dir(img); img.onclick = function() { if (img.src.indexOf('wo') !== -1) { img.src = './man.jpg'; } else { img.src = './woman.jpg'; } } </script>
一個標簽中具體有哪些屬性可以修改, 可以使用console.dir()
函數來獲取DOM API能夠操作的全部屬性, 比如img
元素.
2.5 獲取/修改表單元素屬性
這裡把表單元素單拎出來是因為, 是因為, 表單元素中有一些特別的屬性是普通標簽沒有的, 主要需要區別的是一些表單元素想要獲取其中用戶輸入的內容的話是不能通過innerHTML
拿到的, 這是因為input
, textarea
… 這些標簽元素都是單標簽, 是沒有內容的, 正確的獲取/修改的方式應該是通過這些標簽的value
屬性來進行.
表單計數器
比如input
標簽, 還是在文本框中實現一下計數功能, 同樣的要註意拿到的value
屬性的值也是字符串類型的, 要註意進行類型轉換.
<input type="text" value="0" id='count'> <button id='countAdd'>計數器: 點擊+1</button> <script !src=""> let counterAdd = document.querySelector('#countAdd'); counterAdd.onclick = function () { let num = document.querySelector('#count'); numAdd = parseInt(num.value) + 1 num.value = numAdd; }; </script>
再舉例一個比較常見的場景, 我們平常見的登錄功能中密碼框中的文本可以選擇是否顯示密碼, 這個實現起來其實也很簡單, 通過DOM來修改type
屬性的值即可.
<input type="text" id="pw"> <button>隱藏密碼</button> <script !src=""> let pw = document.querySelector('#pw'); let button = document.querySelector('button'); button.onclick = function() { if (pw.type == 'text') { pw.type = 'password'; button.innerHTML = '顯示密碼'; } else { pw.type = 'text'; button.innerHTML = '隱藏密碼'; } } </script>
全選/取消全選按鈕
這裡再實現一下全選功能, 也就是有若幹個復選框, 點擊全選按鈕, 就會選中所有的選項, 但隻要某個選項取消, 則自動取消全選按鈕的勾選狀態.
實現的基本思路如下:
- 獲取全選按鈕元素, 獲取其按鈕元素
- 註冊全選按鈕的點擊事件, 點擊全選按鈕時, 全選按鈕的checked屬性發生改變, 將checked屬性值賦值給其他按鈕的checked屬性即完成瞭全選.
- 對每一個其他復選按鈕設置點擊事件, 並將狀態與全選按鈕關聯, 即檢查其他復選按鈕是否選中, 如果選中, 則全選按鈕也選中(修改checked值為true), 否則全選按鈕不選中(修改checked值為false).
- 每次點擊其他框都要檢測其他框是否都選中, 以確定全選按鈕的狀態.
<input type="checkbox" id="all">我全都要 <br> <input type="checkbox" class="girl">貂蟬 <br> <input type="checkbox" class="girl">小喬 <br> <input type="checkbox" class="girl">安琪拉 <br> <input type="checkbox" class="girl">妲己 <br> <script> //checked屬性為checked/true表示選中狀態,為空字符串/false表示未選中 //獲取到元素 let all = document.querySelector('#all'); let girls = document.querySelectorAll('.girl'); //給all註冊點擊事件,選中/取消所有選項 all.onclick = function () { for (let i = 0; i < girls.length; i++) { //使girl元素狀態與all相同 girls[i].checked = all.checked; } } //給所有girl元素註冊點擊事件 for (let i = 0; i < girls.length; i++) { girls[i].onclick = function () { //檢測當前是不是所有的girl元素都被選中瞭,確定all的狀態 all.checked = checkGirls(girls); } } //實現checkGirls,檢測當前是不是所有的girl元素都被選中瞭 function checkGirls(girls) { for (let i = 0; i < girls.length; i++) { if (!girls[i].checked) { //隻要一個 girl 沒被選中,就認為結果是 false(找到瞭反例) return false; } } // 所有 girl 中都沒找到反例, 結果就是全選中 return true; } </script>
2.6 獲取修改樣式屬性
第一種方式是通過修改元素的內聯樣式, 即修改元素的style
屬性的值來指定樣式, 這種方式的優先級很高, 適用於該樣式比較少的情況.
點擊文字放大
文字放大效果的實現, 我們可以給文本所在的標簽註冊一個點擊事件, 每點擊一次就將字體大小增大, 即修改CSS的font-size
屬性; 思路很簡單, 但JS代碼的寫法上有一些細節需要註意, 在CSS中是不區分大小寫的, 且在CSS中不需要進行算數運算, 屬性和變量名是采用的是脊柱式命名法, 但-
在JS中就不能用於命名瞭, 所以JS中采用駝峰命名的形式來表示CSS的屬性, 比如font-size
屬性在對應JS的中就為fontSize
瞭.
<div style="font-size:20px;"> 這是一段文本,點擊之後字體放大 </div> <script !src=""> let div = document.querySelector("div"); div.onclick = function() { //1.獲取文字大小屬性 let size = parseInt(div.style.fontSize); console.log("修改前" + size); //2.修改文字大小 size += 5; //3.寫回到屬性 div.style.fontSize = size + "px"; console.log("修改後" + size); } </script>
還有一種修改樣式的方式可以通過修改類屬性來達到修改樣式的效果, 可以通過元素.className
來獲取/修改類屬性的值, 由於class
是 JS 的保留字, 所以這裡獲取類屬性的名字叫做className
.
實現夜間/日間模式的切換
實現點擊界面, 切換日間模式和夜間模式
<div class="container light"> 這是一大段話. <br> 這是一大段話. <br> 這是一大段話. <br> 這是一大段話. <br> </div> <style> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; } .container { width: 100%; height: 100%; } .light { background-color: #f3f3f3; color: #333; } .dark { background-color: #333; color: #f3f3f3; } </style> <script !src=""> let div = document.querySelector('div'); div.onclick = function () { console.log(div.className); if (div.className.indexOf('light') != -1) { div.className = 'container dark'; } else { div.className = 'container light'; } } </script>
3. 操作頁面節點
上述涉及的操作都是針對頁面已有的元素進行操作的, 利用DOM API還可以完成添加/刪除元素的操作.
3.1 新增節點
添加元素主要有兩個步驟, 首先需要創建一個新的創建元素節點, 然後把這個元素節點插入到父元素中就能完成元素的的添加(依賴於DOM樹).
可以使用creatElement
方法來創建一個新的元素:
let element = document.createElement('元素標簽名');
插入到DOM樹中:
父元素.appendChild(創建的子元素);
代碼示例:
關於插入節點還可以使用insertBefore
將節點插入到指定節點之前.
新插入節點的父元素.insertBefore(新插入的元素, 指定節點(將要插在這個節點之前)); <div class="container"> <div>11</div> <div>22</div> <div>33</div> <div>44</div> </div> <script> var newDiv = document.createElement('div'); newDiv.innerHTML = '我是新的節點'; var container = document.querySelector('.container'); console.log(container.children); //children可以返回父元素所有的直系子節點的集合 container.insertBefore(newDiv, container.children[0]); </script>
3.2 刪除節點
刪除節點操作就很簡單瞭, 語法如下:
父元素.removeChild(需要刪除的子元素);
代碼示例, 比如刪除上面代碼無序列表中的33
這個元素.
三. 綜合案例
1. 猜數字
目標頁面如下, 系統可以自動生成[1, 100]
之間的隨機數, 用戶輸入猜測數字, 能夠提示用戶數字是猜大瞭還是猜小瞭.
這裡的邏輯很簡單就不做過多的贅述瞭, 最關鍵的是JS中隨機數的獲取, 我們可以通過Math.random()
函數來獲取隨機數, 該函數生成隨機數的范圍是[0,1)
區間內的一個小數, 我們需要的是[1,100]
之間的整數, 我們可以乘上100
後再拿到整數部分+1
就能得到目標區間的數瞭.
<button id="flash">重開一局</button> <div>請輸入要猜的數字</div> <input type="text"> <button id="submit">提交</button> <!--使用這個div來顯示猜測結果--> <div class="result"></div> <script> //1.生成一個1-100隨機的整數 let toGuess = parseInt(100 * Math.random()) + 1; console.log(toGuess);//用於測試,方便查看猜測結果 //2.進行猜數字操作,比較用戶輸入的數和生成的隨機數 let input = document.querySelector('input'); let resultDiv = document.querySelector('.result'); let submit = document.querySelector('#submit'); submit.onclick = function() { //取出輸入框中的內容 if (input.value == '') { //輸入框沒有值,用戶啥都沒輸入,直接返回 return; } let inputNum = parseInt(input.value); //比較大小關系 if (inputNum < toGuess) { //小瞭 resultDiv.innerHTML = '猜小瞭'; } else if (inputNum > toGuess) { //大瞭 resultDiv.innerHTML = '猜大瞭'; } else { //猜對瞭 resultDiv.innerHTML = '猜對瞭'; } } //3.刷新頁面 let flash = document.querySelector('#flash'); flash.onclick = function() { location.reload(); } </script>
實際效果:
2. 表白墻
目標頁面如下, 點擊提交, 能夠把用戶輸入的話, 顯示在頁面中, 點擊撤銷, 能夠撤回最後一條顯示在頁面的話.
這個案例也沒有難點, 隻是的的揉合東西更多瞭一些, 前端頁面是通過HTML加上CSS彈性佈局實現的, 交互通過JavaScript DOM實現.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表白墻</title> <style> * { /* 消除瀏覽器的默認樣式 */ margin: 0; padding: 0; /* 保證盒子不被撐大 */ box-sizing: border-box; } .container { width: 600px; margin: 20px auto; } h1 { text-align: center; } p { text-align: center; color: #666; margin: 20px 0; } .row { /* 開啟彈性佈局 */ display: flex; height: 40px; /* 水平方向居中 */ justify-content: center; /* 垂直方向居中 */ align-items: center; } .row span { width: 80px; } .row input { width: 200px; height: 30px; } .row button { width: 280px; height: 30px; color: white; background-color: orange; /* 去掉邊框 */ border: none; border-radius: 5px; } /* 點擊的時候有個反饋 */ .row button:active { background-color: grey; } </style> </head> <body> <div class="container"> <h1>表白墻</h1> <p>輸入內容後點擊提交, 信息會顯示到下方表格中</p> <div class="row"> <span>是誰: </span> <input type="text"> </div> <div class="row"> <span>對誰: </span> <input type="text"> </div> <div class="row"> <span>說: </span> <input type="text"> </div> <div class="row"> <button id="submit">提交</button> </div> <div class="row"> <button id="revert">撤銷</button> </div> <!-- <div class="row"> xxx 對 xx 說 xxxx </div> --> </div> <script> // 實現提交操作. 點擊提交按鈕, 就能夠把用戶輸入的內容提交到頁面上顯示. // 點擊的時候, 獲取到三個輸入框中的文本內容 // 創建一個新的 div.row 把內容構造到這個 div 中即可. let containerDiv = document.querySelector('.container'); let inputs = document.querySelectorAll('input'); let button = document.querySelector('#submit'); button.onclick = function() { // 1. 獲取到三個輸入框的內容 let from = inputs[0].value; let to = inputs[1].value; let msg = inputs[2].value; if (from == '' || to == '' || msg == '') { return; } // 2. 構造新 div let rowDiv = document.createElement('div'); rowDiv.className = 'row message'; rowDiv.innerHTML = from + ' 對 ' + to + ' 說: ' + msg; containerDiv.appendChild(rowDiv); // 3. 清空之前的輸入框內容 for (let input of inputs) { input.value = ''; } } let revertButton = document.querySelector('#revert'); revertButton.onclick = function() { // 刪除最後一條消息. // 選中所有的 row, 找出最後一個 row, 然後進行刪除 let rows = document.querySelectorAll('.message'); if (rows == null || rows.length == 0) { return; } containerDiv.removeChild(rows[rows.length - 1]); } </script> </body> </html>
實際效果:
總結
到此這篇關於JavaScript DOM API的使用教程及綜合案例的文章就介紹到這瞭,更多相關JavaScript DOM API使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- JavaScript深入介紹WebAPI的用法
- Python全棧之學習JS(3)
- HTML+CSS+JS實現的簡單應用小案例分享
- js實現添加刪除表格操作
- JavaScript操作元素教你改變頁面內容樣式