---
# System prepended metadata

title: 1202 JS應用

---

# 1202 JS應用
例題1
```
<script>
    document.body.addEventListener('click', function () {
      document.body.classList.toggle('light')
    })
</script>
```
* 用document.body取得body
* `addEventListener('要監聽的事件', 發生後要執行的動作)`
上面這寫法要寫在body之中，如果寫在head會出現
Uncaught TypeError: Cannot read property 'addEventListener' of null
意思是addEventListener前的元素為null，因為html是由上到下讀取，寫在head在讀取到document.body時，瀏覽器還未知道body存在
所以通常會使用
`window.addEventListener('DOMContentLoaded', 動作 )`
讓瀏覽器讀取完全部html再執行動作，所以寫在head時要改成
* classList是個物件，代表指定物品的類別集合
toggle('類別名稱') 有指定的類別就消除，沒有就加上
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
例題2
將JS寫在head
```
<script>
    window.addEventListener('DOMContentLoaded', function () {
      document.getElementById('toggle').addEventListener('click', function () {
        document.body.classList.toggle('light')

        if (document.getElementById('toggle').textContent === '關') {
          document.getElementById('toggle').textContent = '開'
        } else { document.getElementById('toggle').textContent = '關' }
      })
    })
  </script>
```

* `window.addEventListener('DOMContentLoaded', function(){function內容})`
讓瀏覽器在讀取完整個頁面再執行JS，就不會有例題1未定義的狀況
DOMContentLoaded事件是當document被完整的讀取跟解析後就會被觸發,不會等待 stylesheets, 圖片和subframes完成讀取
[https://developer.mozilla.org/zh-TW/docs/Web/Events/DOMContentLoaded](https://)

* getElementById選取DOM中擁有指定id的第一個物件
* textContent可更換物件內容，未更換時代表物件原內容
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
例題3
```
window.addEventListener('DOMContentLoaded', function() {
  document.getElementById('on').addEventListener('click', function() {
    document.body.classList.add('light');

    document.querySelector('.status span').textContent = '開';

    const statusDiv = document.querySelector('.status');
    statusDiv.classList.remove('off');
    statusDiv.classList.add('on');
  });

  document.getElementById('off').addEventListener('click', function() {
    document.body.classList.remove('light');

    document.querySelector('.status span').textContent = '關';

    const statusDiv = document.querySelector('.status');
    statusDiv.classList.remove('on');
    statusDiv.classList.add('off');
  });
});
```
* querySelector為java中的css選取器，以相同方式選取.class #id
這裡不是用一個開關控制，所以不適合用toggle切換
要用remove和add來改變兩個按鈕的class
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
例題4
```
window.addEventListener('DOMContentLoaded', function () {
  document.getElementById('create-element').addEventListener('click',
    function () {
      // debugger
      const div = document.createElement('div')
      div.className = 'time'
      div.textContent = (new Date()).toString()
      document.querySelector('.right').appendChild(div)
    })

  document.getElementById('reset-inner-html').addEventListener('click',
    function () {
      document.querySelector('.right').innerHTML = '<div class="title">DOM practice...</div>'
    })

  document.getElementById('remove').addEventListener('click',
    function () {
      // if (document.querySelector('.time:last-child'))
      //   document.querySelector('.time:last-child').remove()
      if (document.querySelector('.time')) {
        document.querySelector('.right').removeChild(document.querySelector('.time'))
      }
    })

  document.getElementById('create-element-insert-adjacent').addEventListener('click',
    function () {
      const div = document.createElement('div')
      div.className = 'time'
      div.textContent = 'A' + (new Date()).toString()
      document.querySelector('.title').insertAdjacentElement('afterend', div)
    }
  )
})
```
* createElement('名稱')建立新物件
className 
* 父層.appendChild(要增加的物件)只能加在最底部
innerHTML 改變內容包含html宣染（能力強大有風險）
* 父層.removeChild(指定刪除的物件)
* 要刪除的物件.remove()
* 兩種刪除的要考慮刪除對象不存在的情況，在開發者工具會報錯，可以用if來處理，刪除對象存在時才刪除
* 參考位置的物件.insertAdjacentElement（'位置',要增加的物件）
有四種位置參考
```
beforebegin
<P>
afterbegin
.....
beforeend
</P>
afterend
```
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
例題5
```
$(window).ready(function () {
  let cnt = 0, timer = null
  $('button').click(function () {

    if (timer) {
      $('button').text('start')
      $('#running').slideUp()
      clearInterval(timer)
      timer = null
    } else {
      $('button').text('pause')
      $('#running').slideDown()

      timer = setInterval(function () {
        cnt += 1
        $('#seconds').text(cnt)
        $('.dots div:last-child').prependTo($('.dots'))
      }, 1000)
    }
  })
})
```
* $()為jQuery選取器用法同CSS選取器
* 物件.slideUp滑動效果向上隱藏
* 物件.slideDown滑動向下顯示
* setInterval(動作,毫秒) 每多少毫秒執行一次的動作
* clearInterval清除setInterval設定的動作
* 要移動的物件.prependTo(目標元素) 在目標元素開頭插入 
* 要移動的物件.appendTo(目標元素) 在目標元素結尾插入 

timeout = setTimeout(...)
clearTimeout(timeout)
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
例題5 純JAVA Script寫法
```
window.addEventListener('DOMContentLoaded', function () {
  let cnt = 0, timer = null
  document.querySelector('button').addEventListener('click', function () {
    const button = document.querySelector('button')
    const running = document.getElementById('running')

    if (timer) {
      button.textContent = 'start'
      running.classList.remove('Slide')
      clearInterval(timer)
      timer = null
    }
    else {
      button.textContent = 'pause'
      running.classList.add('Slide')
      timer = setInterval(function () {
        cnt += 1
        document.getElementById('seconds').textContent = cnt
        let list = document.querySelector('.dots')
        let moveDiv = document.querySelector('.dots div:last-child')
        list.insertBefore(moveDiv, list.childNodes[0])
      }, 1000)
    }
  })
})
```

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
querySelector選取器(類似CSS選取器)
windows
location
