---
# System prepended metadata

title: 進階 DOM 操作
tags: [JS 直播班 - 2025 秋季班]

---

>若有任何疑問請至 Discord「作業討論」頻道討論

# 進階 DOM 操作
## 本章節我們要學什麼？

延續基礎 DOM 章節，本次將會考驗同學們完成整套具備實際功能、邏輯更為複雜的產品。
部分題目下方附有 keywords，表示該題目運用到課堂外的語法或技巧，同學可依照 keywords 搜尋了解概念。

:::success
本章節專注在功能的邏輯實作，僅會提供最基礎的樣式與架構。歡迎同學自行延伸功能、樣式與創造有趣的內容！
:::
:::warning
本章節考驗同學對方法的靈活運用，以下是助教推薦的文章可一邊溫習一邊練習題目。

* [(上週章節) DOM 操作基礎](https://hackmd.io/sYlcUD-wTimN0NsPrfGH1w)
* [(Ray) 關於 JavaScript 陣列 20 種操作的方法](https://israynotarray.com/javascript/20190421/1216566123/)
* [(卡斯伯) JavaScript 陣列處理方法](https://www.casper.tw/javascript/2017/06/29/es6-native-array/)
* [(MDN)Object.prototype.hasOwnProperty()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)
* [(Javascript.info)Focus/blur 事件](https://zh.javascript.info/focus-blur)
* [(MDN)表單數據檢驗](https://developer.mozilla.org/zh-CN/docs/Learn/Forms/Form_validation)
:::


## 題目一：無障礙彈跳視窗


<img loading="lazy" src="https://i.imgur.com/ifTpZUJ.gif">

### 請達成以下功能：
- [ ] **(打開) > 當點擊「彈跳視窗按鈕」，打開彈跳視窗**
    - [ ] 將焦點 (focus) 放在「OK 按鈕」上，方便鍵盤用戶選取視窗內的選項
    - [ ] 避免使用者在打開視窗的狀況下頁面是可滑動的
    - [ ] 點擊彈跳視窗以外的區域或點選 OK 來關閉

- [ ] **(關閉) > 當按下「ESC」或點擊「OK 按鈕」，關閉彈跳視窗**
    - [ ] 將焦點放在「打開彈跳視窗」按鈕上

### 參考資源
:::spoiler HTML
``` html
<div role="dialog" aria-labelledby="dialog_title">
  <div>
    <h2>Dialog Example</h2>
    <p>Here is some demo text</p>
    <button>OK</button>
  </div>
</div>

<button>打開彈跳視窗</button>
```
:::

:::spoiler CSS
``` CSS
*, *::before, *::after {
  box-sizing: border-box;
}

img {
  display: block;
}

body {
  background: teal;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
}

button:focus, button:hover {
  outline: 2px solid blue;
  outline-offset: 2px;
}

.dialog {
  position: fixed;
  top: 0;
  left: 0;
  display: none;
  justify-content: center;
  align-items: center;
  z-index: 100;
  width: 100%;
  height: 100%;
}
.dialog::after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: black;
  opacity: 0.5;
  z-index: -1;
}

.dialog--active {
  display: flex;
}

.dialog__window {
  background-color: lightgray;
  padding: 1rem;
}
```
:::
✨keywords：element.focus()


## 題目二：書籍蒐尋器
<img loading="lazy" src="https://i.imgur.com/BmdPlQl.gif">

### 請達成以下功能：
- [x] (加載網頁時) > 將預備好的資料注入在網頁上，呈現：「書名 - 介紹」的清單。
- [x] (用戶輸入時) > 從預備好的資料中搜尋，並過濾所有清單。

### 參考資料
:::spoiler HTML
``` HTML
<form autocomplete="off">
  <div>
    <input type="text" name="searchBook" placeholder="搜尋書籍" required>
    <ul>
    </ul>
  </div>
</form>

<ul>
</ul>
```
:::
✨keywords：includes()、contains()、input event

## 題目三：回饋跑馬燈
<img loading="lazy" src="https://i.imgur.com/ZBTpcnW.gif">

### 請達成以下功能：
- [x] (加載網頁時) > 將預備好的資料注入在網頁上，卡片內容有：圖片、標題、內文。
- [x] (點擊上一步) > 卡片向前。
- [x] (點擊下一步) > 卡片向後。
- [x] (其他) > 當到資料頭、尾便不能再往前、往後
- [x] (其他) > 請嘗試抽離寫死的邏輯，將「最大卡片數量」與「初始卡片位置」改為可輸入的變數。

### 參考資料
:::info
圖片使用假圖即可，推薦 [Lorem Picsum](https://picsum.photos/)
:::
:::spoiler HTML
```html
<div>
  <div></div>
  <div>
    <button>prev</button>
    <button>next</button>
  </div>
</div>
```
:::


## 題目四：步驟表單
<img loading="lazy" src="https://i.imgur.com/AUtq91s.gif">

### 請達成以下功能：
- [x] (點擊上一步) > 回到上個步驟
- [x] (點擊下一步) > 驗證後到下個步驟，如是最終步驟，console.log 表單資料
- [x] (驗證) > 當點擊下一步時驗證當前步驟中的輸入內容是否都和規，如不合規，對焦於不和規的輸入上，並且更改其樣式屬性提醒用戶。

### 參考資料

:::spoiler HTML
```htmlembedded
<h1>步驟表單</h1>

<form>
  <!-- 01 -->
  <div>
    <h2>步驟一</h2>
    <hr>
    <label>
      電子信箱
      <input type="email" placeholder="請輸入電子信箱" required>
    </label>
    <label>
      密碼
      <input type="password" placeholder="請輸入密碼" required>
    </label>
    <div>
      <button type="button">下一步</button>
    </div>
  </div>

  <!-- 02 -->
  <div>
    <h2>步驟二</h2>
    <hr>
    <label>
      地址
      <input type="text" placeholder="請輸入您的地址" required>
    </label>
    <label>
      城市
      <input type="text" placeholder="請輸入您的城市" required>
    </label>
    <div>
      <button type="button">上一步</button>
      <button type="button">下一步</button>
    </div>
  </div>

  <!-- 03 -->
  <div>
    <h2>步驟三</h2>
    <hr>
    <label>
      名稱
      <input type="text" placeholder="請輸入您的名稱" required>
    </label>
    <label>
      電話
      <input type="phone" placeholder="請輸入您的電話" required>
    </label>
    <div>
      <button type="button" data-prev>上一步</button>
      <button type="button" data-next>下一步</button>
    </div>

  </div>
</form>
```
:::
✨keywords：hasAttribute()、checkValidity()、reportValidity()

## 題目五：心理測驗
<img loading="lazy" src="https://i.imgur.com/Kl4rNo4.gif">

### 請達成以下功能：
- [x] (開始測驗) > 進入測驗，隱藏介紹卡片，從資料中生成問題與選項
- [x] (生成問題) > 顯示目前問題長度與目前位置
- [x] (點擊選項或單選框) > 進入下個步驟並記錄此筆資料(種類、分數)
- [x] (提交完最後一個問題) > 顯示詢問姓名問題
- [x] (提交完姓名) > 呈現出問題蒐集出來的資料


### 參考資料
:::spoiler HTML
```htmlembedded
<!-- Intro -->
<div>
  <h1>網頁性格測驗</h1>
  <p>製作網頁是一個多種領域發揮的舞台，助教製作了一款簡易的網頁性格測驗，來測試看看同學們對網頁不同領域的喜好程度～</p>
  <button>開始測驗～</button>
</div>

<!-- Test -->
<div></div>

<!-- Result -->
<div></div>
```
:::
✨keywords：eval()


<!-- 參考答案： 

無障礙彈跳視窗
https://codepen.io/fhljksmg-the-styleful/pen/RNrorde

書籍蒐尋器
https://codepen.io/fhljksmg-the-styleful/pen/WbrorWN

回饋跑馬燈
https://codepen.io/fhljksmg-the-styleful/pen/ZYQBQZp

步驟表單
https://codepen.io/fhljksmg-the-styleful/pen/XJXNXQM

心理測驗
https://codepen.io/fhljksmg-the-styleful/pen/xbZRZeX

答案僅供參考，
答案會使用各種方式書寫(非最佳化)並加上部分解說，
適合初學者還不太會解題或者是該題卡住的同學。
-->