# 瀏覽器上的 JS
### 瀏覽器上的 js 應用範圍:
1. 介面
2. 監聽事件
3. 資料
_
## JavaScript 與瀏覽器的溝通
_
### DOM 文件物件模型
>把文件變成有節點的物件的橋樑
---
### 如何選取元素
- getElementByTagName
- getElementByClassName
- getElementById
- querySelector
querySelector 可能是最好用的一個
跟css選擇器一樣,標籤直接打名稱,id使用#,class使用.,下一層 >
但他只會選到第一個,如果想選多個的話就使用 querySelectorAll
範例:
```
<script>
const elements = document.getElementByTagName(‘div’)
console.log(elements[0])
</script>
*document 是瀏覽器提供的物件,很多 function 都放在這個上面
*<script></script> 要放在body的最下面,才讀取的到全部的程式
```
順利選到元素後,就可以試著
### 改變 CSS
範例
```
<div id=“block”>
hello
</div>
<script>
const element = document.querySelector(“#block”)
element.style.background = “red”
</script>
```
使用的時候不能用 - ,所以例如選 padding-top 的話,使用中括號 [ ] 包起來
```
element.style[“padding-top”] = “10px”
```
或是駝峰式也可以
```
element.style.paddingTop = “10px”
```
但其實一般實務上來說不會這樣去改 CSS
會寫在 style 裡面,例如
```
<style>
.active{
background: red;
}
</style>
```
然後讓 js 動態把 css 加上去
```
<script>
const element = document.querySelector(“#block”)
element.classList.add(“active”)
</script>
```
### 如何把 class 移除
```
element.classList.remove(“active”)
```
另外還有一個功能是 **toggle**,開關的意思,非常好用
```
element.classList.toggle(“active”)
```
---
### 如何改變內容
1. innerText 只抓標籤中的文字
2. innerHTML 抓標籤中全部的東西
3. outerHTML 抓含自己在內及標籤內所有的東西
範例
```
<div id=“block”>
yo
<a>helle</a>
</div>
<script>
const element = document.querySelector(“#block > a”)
element innerText = “ I am a link”
console.log(element.innerText)
</script>
```
**插入與刪除元素:appendChild 與 removeChild**
範例:如何把 a 刪掉 (要先找到他的上一層是誰)
```
<div id=“block”>
yo
<a>helle</a>
</div>
<script>
const element = document.querySelector(“#block”)
element.removeChild(document.querySelector(“a”))
</script>
```
範例:如何新增元素
```
<script>
const element = document.querySelector(“#block”)
const item = document.createElement(“div”) 先建立出元素
item.innerText = “123” 加入文字內容
element.appendChild(item)
</script>
```
範例:如何新增文字內容
```
<script>
const element = document.querySelector(“#block ”)
const item = document.createTextNode(“123”)
element.appendChild(item)
</script>
```
_
## JavaScript 網頁事件處理
### event listen 事件監聽
```
<div id=“block”>
yo
<a>helle</a>
</div>
<script>
const element = document.querySelector('#block')
element.addEventListener('click',onClick) 先建立事件名稱,並傳 function 進去
當此事件發生時,瀏覽器就觸發這個 function,叫做 callback function
接著宣告 function
function onClick( ){
alert('click!')
}
</script>
```
也可以這樣寫
```
<script>
const element = document.querySelector('#block')
element.addEventListener('click',function( ){
alert('click!')
})
</script>
```
- function( )叫匿名函式 anonymous function (跟callback function 沒有關係)
- 除了 click 外事件有很多種,例如 scroll, keyDown等等
_
**使用 function(e) 就可以紀錄事件**
簡單範例,使用按鈕切換背景顏色
```
<body>
<div>
<div id="block">
yo
<input />
<a href="">hello</a>
<button class="chang-btn">change</button>
</div>
</div>
<script>
const element = document.querySelector('.chang-btn');
element.addEventListener('click',function(e){
document.querySelector('body').classList.toggle('active')
});
</script>
</body>
```
```
上面 style 要先寫
<style>
.active{
background-color: red;
}
</style>
```
### 表單事件處理 onSubmit
通常應用在資料輸入的驗證上面
範例
```
<body>
<form class="login-form">
<div>
username:<input name='username'/>
</div>
<div>
password:<input name='password' type='password'/>
</div>
<div>
password again:<input name='password2' type='password'/>
</div>
<input type="submit">
</form>
<script>
const element = document.querySelector('.login-form');
element.addEventListener('submit',function(e){
const input = document.querySelector('input[name=password]')
const input2 = document.querySelector('input[name=password2]')
if(input.value !== input2.value){
alert('密碼不同')
e.preventDefault()
}
});
</script>
</body>
```
### 事件傳遞機制
#### preventDefault 阻止瀏覽器預設行為
範例
```
<style>
.outer{
width: 500px;
height: 200px;
background-color: brown;
}
.inner{
width: 300px;
height: 100px;
background-color: burlywood;
}
</style>
```
```
<body>
<div class="outer">
<div class="inner">
<button class="btn">click me</button>
</div>
</div>
<script>
addEvent('.outer')
addEvent('.inner')
addEvent('.btn')
function addEvent(className){
document.querySelector(className).addEventListener('click',function(){
console.log(className)
})
};
</script>
</body>
```
#### 事件傳遞機制詳解:捕獲與冒泡
接續上面的範例
```
<script>
addEvent('.outer')
addEvent('.inner')
addEvent('.btn')
function addEvent(className){
document.querySelector(className).addEventListener('click',function(){
console.log(className,'捕獲')
},true)
document.querySelector(className).addEventListener('click',function(){
console.log(className,'冒泡')
},false)
};
</script>
```
#### 別向上級回報:stopPropagation
接續上面的範例
```
<script>
addEvent('.outer')
addEvent('.inner')
function addEvent(className){
document.querySelector(className).addEventListener('click',function(){
console.log(className,'冒泡')
})
document.querySelector('.btn').addEventListener('click',function(e){
e.stopPropagation()
console.log('.btn 冒泡')
})
};
</script>
```
**新手 100% 會搞錯的事件機制問題**
```
<body>
<div class="outer">
<button class="add-btn">add</button>
<button class="btn" data-value="1">a</button>
<button class="btn" data-value="2">B</button>
<button class="btn" data-value="3">C</button>
</div>
<script>
let num = 3
const elements = document.querySelectorAll('.btn');
for( i=0; i<elements.length; i++){
elements[i].addEventListener('click',function(e){
console.log(e.target.getAttribute('data-value'))
})
}
document.querySelector('.add-btn').addEventListener('click',
function(){
const btn = document.createElement('button')
btn.setAttribute('data-value',num)
btn.innerText = num
num = num + 1
document.querySelector('.outer').appendChild(btn)
});
</script>
</body>
```
如何監聽所有上面新增的按鈕?
把監聽設在上一層!
#### 事件代理機制 event delegation
```
<body>
<div class="outer">
<button class="add-btn">add</button>
<button class="btn" data-value="1">a</button>
<button class="btn" data-value="2">B</button>
<button class="btn" data-value="3">C</button>
</div>
<script>
let num = 3
document.querySelector('.add-btn').addEventListener('click',
function(){
const btn = document.createElement('button')
btn.setAttribute('data-value',num)
btn.classList.add('btn')
btn.innerText = num
num = num + 1
document.querySelector('.outer').appendChild(btn)
}
);
document.querySelector('.outer').addEventListener('click',
function(e){
if(e.target.classList.contains('btn')){}
alert(e.target.getAttribute('data-value'))
}
);
</script>
</body>
```