---
# System prepended metadata

title: javascript
tags: [javascript]

---

# 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)  
 ![](https://i.imgur.com/KN8a63x.png)
 透過 ==appendChild()== 的方法可以將指定的childNode節點，加入到Node父容器的節點末端
 ![](https://i.imgur.com/srKAhJi.png)
 
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;
        }
```
![](https://i.imgur.com/d6a6vXF.png)

### 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，
當我們ＪＳ設定，選取這三個元素，要是這些元素我們都設定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`

