---
# System prepended metadata

title: JavaScript event
tags: [JavaScript]

---

###### tags: `JavaScript`

# JavaScript event

## addEventListener 監聽綁定
```javascript=
addEventListener('event', function, true / false)
// 第三個參數可不寫，預設 fales
// true (事件氣泡 - event Bubbling) - 從指定元素往內找
// fales (事件捕捉 - event capturing) - 從指定元素往外找

// ex:
addEventListener('click',function(){
},false)
```

```javascript=
<style>
  .all{
    height: 200px;
    width: 200px;
    background: red;
  }
  .box{
    height: 100px;
    width: 100px;
    background: #000;
  }
</style>

<h1>true</h1>
<div class="all">
  <div class="box"></div>
</div>

<script>
  var bodys = document.querySelector('.all');
  var el = document.querySelector('.box');
  el.addEventListener('click',function(){
    console.log('box');
  },true)
  bodys.addEventListener('click',function(){
    console.log('body');
  },true)
  // fales - 從指定元素往外找
  // true - 從指定元素往內找
</script>
```

![](https://i.imgur.com/Cc7wIFa.gif)
![](https://i.imgur.com/26zAtWb.gif)

## stopPropagation - 中止冒泡事件
如果你不希望自己監聽的東西有所衝突，就可以下 stopPropagation() 來阻止冒泡事件
```javascript=
<style>
  .all{
    height: 200px;
    width: 200px;
    background: red;
  }
  .box{
    height: 100px;
    width: 100px;
    background: #000;
  }
</style>

<h1>true</h1>
<div class="all">
  <div class="box"></div>
</div>

<script>
  var bodys = document.querySelector('.all');
  var el = document.querySelector('.box');
  el.addEventListener('click',function(e){
    e.stopPropagation(); // 中止冒泡事件
    console.log('box');
  },false)
  bodys.addEventListener('click',function(){
    console.log('body');
  },false)
  // fales - 從指定元素往外找
  // true - 從指定元素往內找
</script>
```

![](https://i.imgur.com/jqr3PFa.gif)

## preventDefault - 取消預設觸發行為

```javascript=
<a href="https://tw.yahoo.com/" class="link">link</a>
<script>
  var el = document.querySelector('.link');
  el.addEventListener('click',function(e){
   e.preventDefault();
   console.log('已取消連結');
  })
</script>
```
![](https://i.imgur.com/0jE5RxL.gif)


## target - 了解目前所在元素位置

```javascript=
<style>
  .header{
    background: pink;
  }
  .ul{
    padding: 1rem;
  }
  li{
    background: #fff;
    padding: 1rem;
  }
</style>
<header class="header">
  <ul class="ul">
    <li>123456789</li>
  </ul>
</header>
<script>
  var el = document.querySelector('.header');
  el.addEventListener('click',function(e){
   console.log('target:',e.target);
   console.log('nodeName:',e.target.nodeName);
  })
</script>
```
![](https://i.imgur.com/t95UteU.gif)

## change - 表單內容更動內容時觸發

```javascript=
<select name="area" id="area">
  <option value="前鎮區">前鎮區</option>
  <option value="苓雅區">苓雅區</option>
</select>
<ul class="list"></ul>

<script>
  var area = document.getElementById('area');
  var list = document.querySelector('.list');
  var country = [
    {
      farmer: '查理',
      place: '前鎮區'
    },
    {
      farmer: '小花',
      place: '前鎮區'
    },
    {
      farmer: '大白',
      place: '苓雅區'
    },
  ]
  var countryLen = country.length;
  function updatedList(e) {
    var select = e.target.value;
    var str = ''; // 組資料用
    for(var i=0;countryLen>i;i++){
      if(select === country[i].place){
        str += `<li>${country[i].farmer}</li>`
      }
    }
    list.innerHTML = str;
  };
  area.addEventListener('change', updatedList, false)
</script>
```
![](https://i.imgur.com/4itrmfx.gif)

## keyCode - 鍵盤事件

```javascript=
<style>
  .list{
    position: relative;
    width: 100px;
    height: 100px;
    list-style-type: none;
    background: pink;
  }
  .round{
    position: absolute;
    bottom: 0;
    width: 25px;
    height: 25px;
    background: #000;
    border-radius: 50%;
    transition: 1s cubic-bezier(0.25, 0.1, 0.49, 0.16);
  }
  .round-1{
    left: 10px;
  }
  .round-2{
    left: 50%;
    transform: translateX(-50%);
  }
  .round-3{
    right: 10px;
  }
</style>
  <ul class="list">
    <li class="round round-1"></li>
    <li class="round round-2"></li>
    <li class="round round-3"></li>
  </ul>

<script>
  var body = document.body;
  var list = document.querySelector('.list');
  function keydown(e) {
    switch(e.keyCode){
      case 49: // 1
        console.log(e.keyCode);
        document.querySelector('.round-1').style.bottom = '200px'
      break;
      case 50: // 2
        console.log(e.keyCode);
        document.querySelector('.round-2').style.bottom = '200px'
      break;
      case 51: // 3
        console.log(e.keyCode);
        document.querySelector('.round-3').style.bottom = '200px'
      break;
    }
  };
  body.addEventListener('keydown', keydown, false)
</script>
```
![](https://i.imgur.com/kIFe2oJ.gif)

## blur - 離開焦點時進行事件觸發

input 如果為空白會錯出 error msg 
```javascript=
<style>
input{
  width: 50px;
}
.error{
  display: none;
  color: red;
}
.error.show{
  display: block;
}
</style>
價目表：咖啡50元，蛋糕100元<br />
我要
<input type="text" class="input1" value="0">
杯咖啡，
<input type="text" class="input2" value="0">
份蛋糕
<button type="button" class="btn">計算</button>
<div class="error">數量錯誤</div><br />
總共 <span class="moneys">0</span>元
<script>
  var money = '';
  var input1 = document.querySelector('.input1');
  var input2 = document.querySelector('.input2');
  var error = document.querySelector('.error');
  var btn = document.querySelector('.btn');
  var moneys = document.querySelector('.moneys');
  function checkNum(e) {
    if(e.target.value === ''){
      error.classList.add('show')
    }else{
      error.classList.remove('show')
    }
  };
  function checkMoney(e) {
    if(input1.value !== '' && input2.value !== ''){
      error.classList.remove('show')
      money = input1.value * 50+input2.value * 100
    }else{
      error.classList.add('show')
      money = 0;
    }
    moneys.textContent = money;
  };
  input1.addEventListener('blur', checkNum, false)
  input2.addEventListener('blur', checkNum, false)
  btn.addEventListener('click', checkMoney, false)
</script>
```
![](https://i.imgur.com/02so1XW.gif)

## mouse - 當滑鼠滑入指定內容時觸發

觸發 console.log
```javascript=
<style>
.box{
  width: 50px;
  height: 50px;
  background: #000;
}
</style>
<div class="box"></div>
<script>
  var box = document.querySelector('.box');
  function mousemove(){
    console.log('mousemove start');
  }
  box.addEventListener('mousemove', mousemove, false);
</script>
```
![](https://i.imgur.com/hkQGspn.gif)

## screen、page、client - 網頁座標箇中差異

- event.screenX、event.screenY (整個螢幕的解析度大小)

滑鼠相對於用戶顯示器螢幕左上角的 X,Y 坐標。標準事件和IE事件都定義了這2個屬性

- event.pageX、event.pageY (整個網頁內容長度 & 寬度)

類似於event.clientX、event.clientY，但它們使用的是文檔坐標而非窗口坐標。這2個屬性不是標準屬性，但得到了廣泛支持。IE事件中沒有這2個屬性。

- event.clientX、event.clientY (瀏覽器窗口的大小)

滑鼠相對於瀏覽器窗口可視區域的X，Y坐標（窗口坐標），可視區域不包括工具欄和滾動條。IE事件和標準事件都定義了這2個屬性

## 事件監聽優化篇 - 從父元素來監聽子元素內容

### 題目：點擊 li 顯示裡面的內容

由下面的 範例一 得知 querySelector 只會取得第一筆，所以點選阿花並不會出現
```javascript=
// 範例一
<style>
  .list{
    background: #989898;
    padding: 50px;
  }
</style>
<ul class="list">
  <li>小白</li>
  <li>阿花</li>
</ul>
<script>
  var box = document.querySelector('.list li');
  function listName(e){
    console.log(e.target.textContent);
  }
  box.addEventListener('click', listName, false);
</script>
```
![](https://i.imgur.com/1Mt5Nao.gif)


範例二 querySelector 選擇父元素點選正常，但是點擊 ul 會出現 ul 裡面的內容，所以必須加入判斷式讓它過濾不必要的內容
```javascript=
// 範例二
<style>
  .list{
    background: #989898;
    padding: 50px;
  }
</style>
<ul class="list">
  <li>小白</li>
  <li>阿花</li>
</ul>
<script>
  var box = document.querySelector('.list');
  function listName(e){
    if(e.target.nodeName !== "LI"){return} // 很重要
    console.log(e.target.textContent);
  }
  box.addEventListener('click', listName, false);
</script>
```
![](https://i.imgur.com/2LQZh0h.gif)
![](https://i.imgur.com/PFFnL2O.gif)

