# javascript
1. 代碼必須位於`<script>` 與`</script>`之間
2. 可以在head 或body裡任意編輯,比較適合放在body裡,速度較快
* 3. 也可以放在外部檔案如用link或是script src 連結。ex. xxx.js在html檔用link連結
- 優勢:
- 使html 與js更易閱讀,畫面不用一直拉
- 已儲存的js文件
- 可以加速頁面的加載
- 如果需要連結多個js文件就用多個`script`標籤
4. 以分號結束不是必須的,但建議這樣做
5. js會忽略多個空格,空格寫在程式碼是為了讓讀者閱讀方便
6. 註解單行註釋以`//`表示,多行註釋以`/* */`表示
7. 樣板字串:
- 以往可能要靠` "` 以及`+`連作字串及數字的連結,這種寫法會讓程式碼變得很攏長且難以閱讀,再多行的時候也必須插入反斜線來換行,但在js可以使用`${}`來加入變數或函式,也可在`${}`再加入函式。
### 字面值與變量
1. string number就是單值,可單獨存在有意義,string需要`" " or ' '`包覆起來。
如果把數字包覆在`" "`
3. 變量variable用來儲存資料,以`var`宣告變量並用`=` 賦值,命名方式常以駝峰式ex. `FirstName`每個字的第一個字大寫。
4. `==`才是等於
5. 標示符是一個名詞,用來命名變量。
js對於大小寫很敏感,像是`bigpig` 跟`bigPig`是兩個完全不同的變量
6. 變量聲明是沒有值的,必須用`=`賦值給所聲明的變量
在腳本開頭聲明所有的變量是一個好習慣!
7. 一個句子也可以有多個變量,用逗號隔開
```
var person = "chris" , herCar = "toyota" , price = 10000;
```
8. 變量可以儲存多種數據類型:
- 數字 `var legth =7;`
- 用`+`在數字與數字間代表加法,在字串間就是串接
```
var x = 10;
var y = 20;
console.log("this result is:"+x+y)//以為結果是30(x)
//結果是1020,字串用+號就只是串接
```
- 屬性/方法
- toString()轉換為字串的方法
- valueOf()以數值返回數值
- Number()將變量轉換成數值
- parseInt()將變量返回數值,但只返回首個數字
- parseFloat() 將變量返回數值可以接受小數了,但只返回首個數字
- 字串`var lastName = "Lin";`
- 有原始字串值,也可以透過new定義為對象,ex.
```
var firstName = "chrislinlin"
var firstName = new String("chrislinlin")
```
- 用`==`相同的字串得到的結果可以是true
用`===`則必須要有類型與值都相等結果才可以是true
```
var x = "chrislin"
var y = new String("chrislin")
//(x===y)得到的結果是false 因為一個是字串 一個是對象
```
- 屬性/方法:
- length屬性返回字串的長度
- indexOf()方法返回字串中指定資料/*首次*/出現在索引的位置
- lastIndexOf()方法返回字串中指定資料/*最後一次*/出現在索引的位置
- 如果未找到資料`indexOf()`與`lastIndexOf()`都是回返回-1
- search() 方法返回字符串中指定資料第一次出現的位置
search()跟indexOf()很像只是indexOf()可以設置第二個參數指定查詢的位置
-
9. 用type of 確認數據類型
- 在js中沒有值的變量其值為undefined,用type of 也是undefined
```
typeof "Bill" // 返回 "string"
typeof 3.14 // 返回 "number"
typeof true // 返回 "boolean"
typeof false // 返回 "boolean"
typeof x // 返回 "undefined" (假如 x 没有值)
```
### Undefined 和null 值相等但類型不相等
```
typeof undefined // undefined
typeof null // object
null === undefined // false
null == undefined // true
```
- 變數提升(variable hosting)不管在哪一行使用了變數,都視為在第一行做宣告,還是會受到function scope限制
- 在宣告之前用let 是無法存取的,但var可以
```.js
console.log(x); //undefined
var x =10;
console.log(x); //10
function say({
console.log(x); //undefined
var =20;
console.log(x); //20
```
})
### 函式function
- 函式用來為執行特定任務時的程式碼
- 函式會在被調用時被執行,調用時要是函式內有內有相同變數,記得要用==var/ let== 區別,不然後面那個變數會汙染整個環境,例子:
```.js
var a=10;
function hello(){
a =15; //記得要加var/ let
console.log(a);
}
hello();
console.log(a); //15 因為被污染了!
//15
```
- 函式有兩種表達方式
- 函式陳述式:受到hoisting 變數提升影響,在宣告前就可以執行
```.js
hellofunction();
function hellofunction(){
console.log("hihi"); // hihi
}
```
- 函式表達式
```.js
hellofuntion();
var hellofunction = function(){
console.log('hihi'); //會失敗,因為表達式要先宣告,才可以用
}
```
- 函式只要定義一次就可以使用多次,而且可以對函式傳遞不同的參數產生不同的結果
- 在函式中宣告的變數只有在函數內才能被執行,稱為局部變量,除了函式外會讀不到。
語法:
`function 函式名(){
要執行的代碼
}`
括號裡面可以放參數,參數間用逗號隔開
`function name(參數1, 參數2, 參數3){
要執行的代碼
}`
- 函式返回
當js執行到return語句時,函式停止運算,並將計算出的值返回給調用者
```
var x = myFunction(2,4)
function myFunction(a, b){
return a*b
//結果是8
}
```
- 匿名函式
- 預計做什麼事執行玩被呼叫或是被放到回調函式,先傳進去等他需要時再被呼叫
- 立即函式:
- 可以立刻被呼叫的函式表達式,
- 表達式就是會回傳值的式
- 使用函式表達式回傳後立即執行
- jquery常使用,可防止污染$
- 用法
- map() 陣列使用 map() 方法呼叫函式的話,就可以讓陣列中每個元素執行完該函式後,將每個元素的執行結果==回傳==到一個新的陣列。
```.html
let A = [9000, 8500, 5500, 6500];
let B = A.map(function (value, index, array) {
return value*2;
});
console.log(A) // [9000, 8500, 5500, 6500] - 原陣列不會被修改
console.log(B) // [18000, 17000, 11000, 13000] - 發財摟 ^____^
```
### 對象
- 在js裡,對象是個是個被命名值的容器,而裡面包含很多值
- 形容對象的東西稱為屬性,像是color以及brand就是形容車子的屬性
```
var car = {color:"red",brand:"BMW"}
```
- 對對象做的動作稱為方法,像是start()/drive()/ stop(),這些方法可以以函數方式被儲存在屬性中
```
var myCar = {color:"red",brand:"BMW", way: function(){return this.color+ " "+this.brand}}
```
這裡的this指得是myCar
### 事件event
- 是指對html元素所做的事像是onload, onclick, onmouseover, onkeydown, onmouseout,像是
```
<button onclick = "displayDate()">現在的時間是</button >
```
- 註冊事件的方法
- `addEventListener()`
- `on-event +html屬性/ 非html屬性`
- html屬性透過 ==on+動作==就可以註冊事件
```
<button id= "btn" onclick="console.log("hihi");">Click</button>
```
- 非html屬性像是,window或是document這種沒有實體物件的元素,透過on+事件處理器來處理事件
```
window.onload=function(){
document.write("hello, chris")
}
```
### DOM document object model
dom定義了
- 作為物件的html元素
- 所有html元素的屬性
- 訪問所有html元素的方法
- 所有html元素的事件
1. 文件的物件也是文件的nodes,可以改變元素的型態、內容和事件作用
2. 實體元素透過 DOM API 取得 DOM 物件後,再透過 on-event 處理器來處理事件
```
<button id ="btn" >click</button>
var btn = document.getElementById('btn');
btn.onclick=function(){
console.log('hhihi');
}
```
4. 先選一個你要的元素
- getElementById
- querySelector('可以加元素、css、#id')
```
docuement.querySlector('.first.span').style.backgroundColor="red" //改變class是 first裡的屬性span的背景顏色
```
```
document.querySlector('li:first-child').style.backgroundColor = "blue";
//改變li裡面的第一個子元素的背景顏色變為藍色
```
- Update Background
- Select using CSS
3. 選多個元素
- getElementByClassName
- getElementByTagName
- querySlectorAll
4. 將建立好的節點加入我們指定的位置
- Node.appendChid(childNode)

透過 ==appendChild()== 的方法可以將指定的childNode節點,加入到Node父容器的節點末端

5. 節點屬性的改變 classlist
- 新增 classList.add
- 減少 classList.remove
- 切換 classList.toggle 當元素上沒有這個CSS類時,它就新增這個CSS類;但若元素已經有了這個CSS類,它就是刪除它。就是反轉操作
- 包含 classList.contain
### 事件物件
1. 註冊事件物件的方法addEventListener 來監聽事件,裡面有三個參數分別是 事件名稱 + 事件處理器 + 捕獲冒泡機智切換
event.target: 觸發DOM的元素,this
event.type: 事件名稱
event.bubble: 事件是否在冒泡時觸發 (T/ F)
```.html
<body>
<span>1111</span>
<span>222</span>
<span>33</span>
<span>4</span>
</body>
```
```.js
const spans= document.querySelectorAll('span');
spans.forEach(function(el, index){
console.log(el);
el.style.padding='35px';
el.style.border= '1px solid black'
el.style.display="block"
el.addEventListener('click',function(e){
console.log(e.target); //得到同樣的東西
console.log(this); //得到同樣的東西
console.log(el); //得到同樣的東西
}
```
### keydown keyup keypress
當鍵盤上一個鍵被按下放開時,就會觸發事件
KeyDown:使用者按下按鍵時發生
KeyPress:使用者按下按鍵,並且產生一個字元時發生
KeyUp: 使用者釋放某一個按鍵時觸發
完整的 keypress 過程分為兩個部分:1. 按鍵被按下;2. 按鍵被鬆開。
當按鈕被按下時,發生 keydown 事件。
keydown() 方法觸發 keydown 事件,或規定當發生 keydown 事件時執行的函式。
```html
<body>
<h1>aaaaaaa</h1>
<input type="text" name="newItem">
</body>
```
```.js
const ele = document.querySelector('input');
ele.addEventListener('keypress',addItem);
function addItem(event){
document.querySelector("h1").textContent=ele.value;
//再input輸入內容,h1 text就會隨機改變
}
```
#mouseover mouseout
- 當滑鼠經過離開時,會觸發事件
```.html
<ul class="second">
<li class="first"><a href="#">l1</a></li>
<li class="first"><a href="#">l2</a></li>
<li class="first"><a href="#">l3</a></li>
<li class="first"><a href="#">l4</a></li>
<li class="first"><a href="#">l5</a></li>
<li class="first"><a href="#">l6</a></li>
<li class="first"><a href="#">l7</a></li>
</ul>
```
```.js
const lis = document.querySelectorAll('li'); //選取li元素
for( let x=0;x<lis.length;x++){ //使用for迴圈把li元素都加上mouseover事件物件,當滑鼠滑過背景變成黃色
lis[x].addEventListener('mouseover',function(e){
this.classList.add('red');
this.style.backgroundColor="yellow"
})
lis[x].addEventListener('mouseout',function(e){
this.classList.remove('red')
this.style.backgroundColor="transparent"
})
}
```
### 迴圈- switch
- break有沒有很重要!像下面這情況,一開始假設`x=2`,
- 第一個case:因為x不等於一,不成立直接進下一個case。
- 第二個case:因為x等於二,成立,==因為沒有break==又在進下一個case。
- 第三個case:==因為上面x等於二成立==,不管這個case有沒有符合都會==先執行這個case的結果==,就算不成立也會執行,因為沒有break又在進下一個case。
- 最後一個case:==因為上面x等於二成立==,不管這個case有沒有符合都會==先執行這個case的結果==,就算不成立也會執行,因為沒有break又在進下一個case。
```.js
var x =2;
switch (x){
case x=1:
console.log("good");
// break;
case x=2:
console.log("goo");
// break;
case x=3:
console.log("god");
// break;
default:
console.log("fale");
break;
}
```

### break & continue
continue語句(不論有無標籤的引用)只能用於==跳過==一個迭代。
break 語句,若没有標籤引用,只能用於跳出一個循環或一個 switch。
如果有標籤引用,則 break 語句可用於跳出任意代碼塊:
### 表達式expression/ 陳述句 statement
表達式會回傳值,陳述句不會
### window
1. window是瀏覽器的根物件
```.js
function abc(){
z=1; //當你沒有把他宣告成
,沒有給他var/ let/ const 他就會變成全域的屬性
}
abc();
window.z //1
```
# 阻止事件冒泡
- event.propagation
```.html
<div class="outside">
<div class="inside">
<input class="clickMe" type="button" value="button">
</div>
```
在html outside class裡在設定inside class inside class 裡在設定一個button,
當我們JS設定,選取這三個元素,要是這些元素我們都設定console.log("印出xxx"),
只要我們點擊最裡面的元素,他都會事件冒泡,印出到最外面那層的console.log
- 如何阻止?
- 利用 event.stopPropagation(),event是個參數,可以改成其他的
```.js
document.querySelector('.outside').onclick = ()=>{
console.log('外面的div')
}
document.querySelector('.inside').onclick = ()=>{
console.log('裡面的div')
}
document.querySelector('.clickMe').onclick = (event)=>{
console.log('那個button')
event.stopPropagation() // 在想阻止冒泡那層,加上stopPropagation
}
```
###### tags: `javascript`