- HW1 明天做,眼睛酸
 
參考範例:hw2 FAQ 頁面(請先寫完作業再看)
1'30" 開始切版
9'30" 收縮功能
12'35" 點擊事件
document
  .querySelector('.questions')
  .addEventListener('click', function(e) {
    const clickArea = e.target.closest('.q-block')
    if (clickArea) {
      clickArea.classList.toggle('q-block--hide')
    }
  })
// 先選到 questions 這個 class 的元素
// 監聽 questions 裡面的 click 事件
// 給一個變數叫做點擊範圍
// e.target 觸發事件的元素(點擊的地方)
// .closest 從當前元素開始,往回到第一個祖父元素
// e.target.closest('.q-block') 在 q-block 裡面發生點擊事件,
// 就從自己本身開始找,直到第一個祖父元素
// classList.toggle(),有就刪除,沒有就加回來(像是電燈開關吧,
// 按一下開燈,再按一下關燈)
// 如果「有偵測到點擊事件,就把留言打開或關閉」
參考資料:
- 在 RWD 那裡調半天,不太懂怎麼調,應該會有一個固定模式的,像是 320, 768, 1024 有四種組合之類的?
 
參考範例:hw3 todo list(請先寫完作業再看)
0 - 3'30": html
3'33": 排版
7'11" - 10'25": 新增功能
10'29" - 15'51": 過濾輸入字串,跳脫 js escape
- 跟資安有關,在 W11, W12 會學到
 - 特別注意輸入字串的樣式,像是如果輸入標籤之類的,也會正確解讀為「文字」而不是標籤,跟那個網址後面的 & 有關,關鍵字「encode html」
 
15'50" - 18'10": appendChild 的運作模式
- 對節點使用 appendChild 時,會對節點做移動,而不是複製;要真的複製的話,要用 cloneElement or Node.cloneNode(),我現在還不是很清楚要怎麼做,先放著。
 
18'38" - 22'48": 刪除功能
22'48" - 26'50": check/uncheck
- classList.toggle() 不適用,因為有分 checked / unchecked
 
27'00": 重點在於事件代理人
- 完全想不到要注意 "escapeHtml"
 - 也沒有注意到「有輸入才能新增」 "if (!todolist) return"
 - 刪除功能裡面的 target 不知道要取什麼名字更好?
 
// 當點擊新增按鈕時,取得 input 裡面的資料內容,並新增一個待辦清單欄位
// 新增功能
document
    .querySelector('.create')
    .addEventListener('click', function() {
        const todolist = document.querySelector('.input-todo').value;
        if (!todolist) return
        const addNew = document.createElement('div')
        addNew.classList.add('todo')
        addNew.innerHTML = `
            <input class="check" type="checkbox">
      <div class="todo-list">${escapeHtml(todolist)}</div>
      <button class="delete">x</button>
        `
    document.querySelector('.content').appendChild(addNew)
        document.querySelector('.input-todo').value = ''
    })
    function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, "&")
        .replace(/</g, "<")
        .replace(/>/g, ">")
        .replace(/"/g, """)
        .replace(/'/g, "'")
  }
// 刪除功能
document
    .querySelector('.content')
    .addEventListener('click', function(e){
        const target = e.target
        if (target.classList.contains('delete')) {
            target.parentNode.remove()
            return
        }
      // 完成/未完成功能
        if (target.classList.contains('check')) {
            const chk = target.parentNode.classList
            target.checked?chk.add('done'):chk.remove('done')
        } // eslint 大概不給過吧  
        // if (target.classList.contains('check')) {
        //  if (target.checked) {
        //      target.parentNode.classList.add('done')
        //  } else {
        //      target.parentNode.classList.remove('done')
        //  }
        // }    
    })
- 學習重點就是:
- 選對元素
 - 加監聽器
 - 知道要用哪個函式: https://htmldom.dev/ 超棒網站
- target.classList.contains()
 - target.parentNode.remove()
 - add()
 - .checked
 
 
 


![[19] 原生功能 Natives - Symbol、Native Prototypes](https://static.coderbridge.com/images/covers/default-post-cover-3.jpg)