JavaScript 使用文件物件模型(DOM)與 HTML 進行互動。 DOM 是表示 HTML 的物件樹。您可以使用文件物件存取 HTML,該物件代表整個 HTML 文件。
HTML 文件中的標籤、文本、屬性都被解析成節點(Node),以層級結構表示:
<html>
、<body>
等標籤。class="example"
。HTML 文件中的標籤、文本、屬性都被解析成節點(Node),以層級結構表示:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>Hello World</h1>
<p>This is a paragraph.</p>
</body>
</html>
Document
└── <html>
├── <head>
│ └── <title>
│ └── "Example"
└── <body>
├── <h1>
│ └── "Hello World"
└── <p>
└── "This is a paragraph."
節點關係:
接下來我將示範一些常見的操作 (示範都在vscode 中執行)。
為此,你需要在 vscode 中下載一個延伸模組,下圖所示:
接著,我們需要連結 JS 程式碼,將<script src="script.js"></script>
放置於Body區塊的最後,如下所示。
<script src="script.js"></script>
</body>
接著就可以開始實際操作了。若要進行測試,撰寫完所有程式碼後,右鍵點擊 HTML 程式碼,選擇 Open with Live Server ,接著按下 F12 ,在選項卡中選擇 Console 就可以進行測試囉。
document.getElementById()
,根據ID獲取元素。並使用element.textContent
打印出內容<h1 id="title">Hello, World!</h1>
const title = document.getElementById("title");
console.log(title.textContent); // "Hello, World!"
document.getElementsByClassName()
,根據Class獲取元素,用讀取陣列的方式使我們可以針對每一個項目去做文字的更改:<p class="text">First Paragraph</p>
<p class="text">Second Paragraph</p>
const paragraphs = document.getElementsByClassName("text");
console.log(paragraphs[0].textContent); // "First Paragraph"
paragraphs[1].textContent = "Updated Second Paragraph";
console.log(paragraphs[1].textContent); // "Updated Second Paragraph"
document.querySelector()
,回傳文件第一個符合特定選擇器群體的元素<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
<div>
<p class="text">A paragraph</p>
</div>
const paragraph = document.querySelector(".text");
const listItem = document.querySelector("li");
console.log(paragraph.textContent); // "A paragraph"
console.log(listItem.textContent); // "Item 1"
document.querySelectorAll()
,把所有符合特定選擇器群體的元素選取起來,並存放於一個陣列,用一些陣列的方法使我們可以針對每一個項目去做文字的更改:<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
const listItems = document.querySelectorAll("li");
listItems.forEach((item, index) => {
item.textContent = `Updated Item ${index + 1}`;
});
document.createElement()
,用於創建標籤元素,接著使用appendChild()
將標籤元素附加到某父節點內。<div id="container"></div>
const container = document.getElementById("container");
const newElement = document.createElement("p");
newElement.textContent = "This is a new paragraph.";
container.appendChild(newElement);
element.innerHTML
,允許讀取或寫入 HTML 結構,也就是說可以插入 HTML 標籤和文本內容,非常靈活,不過缺點是安全性較低。容易遭受 XSS攻擊 (一種網站應用程式的安全漏洞攻擊,是代碼注入的一種。它允許惡意使用者將程式碼注入到網頁上,其他使用者在觀看網頁時就會受到影響)。<div id="content"></div>
const content = document.getElementById("content");
content.innerHTML = `<h1>Test</h1>
<p>This is added with innerHTML</p>`;
element.setAttribute()
,為元素創建某個新屬性。<input id="inputField" />
const inputField = document.getElementById("inputField");
inputField.setAttribute("placeholder", "Type here...");
element.removeAttribute()
,移除元素的某個屬性<input id="inputField" placeholder="Type here..." />
const inputField = document.getElementById("inputField");
inputField.removeAttribute("placeholder");
element.classList
,透過這個物件可以動態的在節點的 class 屬性上操作。<div id="box" class="blue"></div>
const box = document.getElementById("box");
box.classList.add("red"); //Add a new class (用來新增一個或多個 CSS 類別到元素中,如果該類別已經存在,不會重複添加。)
box.classList.remove("blue"); //Remove an existing class (用來移除一個或多個 CSS 類別,如果該類別不存在,則不會執行任何動作。)
box.classList.toggle("highlight"); //Toggle a class (如果該類別不存在,則新增該類別,如果該類別已經存在,則移除該類別。)
const box = document.getElementById("box");
box.classList.toggle("highlight"); // 如果 "highlight" 存在就移除,否則新增
box.classList.toggle("highlight", true); // 強制新增 "highlight"
box.classList.toggle("highlight", false); // 強制移除 "highlight"
remove()
,移除元素,若是要隱藏則使用element.style.display = 'none';
<p id="toRemove">This will be removed</p>
const toRemove = document.getElementById("toRemove");
// toRemove.style.display = 'none';
toRemove.remove();
addEventListener()
,可以偵測用戶在瀏覽網頁時的各種操作。像是點擊滑鼠、鍵盤輸入。而我們可以讓其執行一些函數功能。<button id="clickMe">Click Me</button>
const button = document.getElementById("clickMe");
button.addEventListener("click", () => {
alert("Button clicked!");
});
好,目前你對於一些基本的DOM操作有了初步認識,不過有幾處細節需要特別留意。
element.innerText
和 element.textContent
的區別innerText
取得的是被 CSS 調整過樣式後渲染的文字;textContent
則是實際取得節點中的文字內容。
<h1 style="text-transform: uppercase;">Hello world</h1>
const h1 = document.querySelector('h1');
console.log(h1.innerText); // HELLO WORLD
console.log(h1.textContent); // Hello world
第2個例子:
<h1>Hello world<span style="display: none;">Hidden Text</span></h1>
const h1 = document.querySelector('h1');
console.log(h1.innerText); // Hello world
console.log(h1.textContent); // Hello worldHidden Text
第3個例子:
<h1>Hello <br />world</h1>
const h1 = document.querySelector('h1');
console.log(h1.innerText);
// 輸出
Hello
world
console.log(h1.textContent); // Hello world
innerText
回傳的會是換行的結果;textContent
則會忽略掉它。addEventListener()
的其他事件類型:keyup
示範
<h2>文字欄監測範例</h2>
<label for="textInput">請輸入文字:</label>
<input type="text" id="textInput" placeholder="開始輸入文字...">
// 取得輸入框元素
const textInput = document.getElementById("textInput");
// 監聽 keyup 事件,偵測按下按鍵後放開的行為,並觸發後面的函數。
// 而用戶動作的所有相關資訊,將其打包為event這個參數並傳到函數內
textInput.addEventListener("keyup", (event) => {
// 將用戶按下的鍵名打印到主控台
console.log("目前按下的內容:", event.key);
// 將目前文字欄內的所有值打印到主控台
console.log("輸入的內容:", event.target.value); // event.target 會指向觸發該事件的 <input> 元素,也就是文字欄。
});
有了上面的觀念,你也可以開始撰寫一些程式碼的判斷並執行相應的動作,例如:
const textInput = document.getElementById("textInput");
textInput.addEventListener("keyup", (event) => {
if(event.key === "Enter") {
console.log("文字欄內容:", textInput.value);
}
});
addEventListener()
支援許多事件類型,沒有辦法一一示範,不過最基本的觀念掌握好,之後遇到其他事件的處理也都可以快速掌握並使用。