---
# System prepended metadata

title: 前端學習筆記

---

# 前端學習筆記
## 1. 第一周-JavaScript：

###     **一(方法、語法).**
####     常用內建函式or瀏覽器主控台使用語法
        `consle.log() 印在主控台`
        `typeof 查看資料型態`
        `prompt() 跳窗輸入 alert() 跳窗顯示`
        `parseInt() 轉換為整數(Int)`
        `document 此語句於瀏覽器主控台輸入後可查看包含整個HTML的訊息(document.all 解析 DOM 的樹)`
        
####     if...else... 結構
    
        if(條件1){
            (條件達成時執行敘述)
        }else if(條件2){
            (條件達成時執行敘述)
        }else{
            (都不符合以上條件時執行敘述)
        }    
        
####     switch...case...結構
        
        switch (key) {
            case 1:
                (key == 1 執行敘述)
                break;
            case 2:
                (key == 2 執行敘述)
                break;
            default(都沒有的話):
                (都沒有的話執行的敘述)
                break;
                
        **一定要break; 因為條件達到時，執行完敘述必須跳離程式區塊**
        
####     for 迴圈
    
        for(var i = 初始值; i < 終止值; 遞增值++){
            (需要迭代之內容)
        }
    
####     while VS do...while
    
        // 前測式
        while(跳離時條件){
            (需迭代內容)
        }
        
        // 後測式
        do{
            (需迭代內容)
        }while(跳離時條件)
        
####     Callback Function 回呼函數
        
        function heyFunc(myFunction){
            myFunction('Hi!!')
        }
        // 把 console.log()當作參數傳遞進myFunc() -> 使用console.log()去執行myFunc()
        heyFunc(console.log)
        // 把 alert() 當作參數傳遞進myFunc() -> 使用alert()去執行myFunc()
        heyFunc(alert)
        
####     匿名函式(Anonymous Function)
    
        function heyFunc(myFunction){
            myFunction('Hi!!!');
        }
        
        // 匿名函式 -> 以function heyFunc()為例 message:'Hi!!!'
        heyFunc(function(message){
            console.log('message is:', message);
        });
        
####     立即函式(Immediately Invoked Functions Expressions)
    
        (function(name){
            var str = 'Hi, ' + name + ' !'
            console.log(str)
        })('Peter')
        // 函示沒有名稱，立即使用，function前後需有括弧將其保護，否則會出錯，函示結束處須加上參數
        
####     物件宣告與使用
    
        var dog = {
            name: 'Tracy',
            age: 20,
            bow: function(){
                console.log('bow bow')
            }
        }
        // 呼叫 dog 的 name
        dog.name
        
        // key = name, value = 'Tracy'
        dog['name']
        
        // 呼叫 dog 的 bow()
        dog.bow()
        
        // 增加color屬性
        // 方法一
        dog.color = 'white';
        console.log(dog);
        
        // 方法二
        dog['size'] = 'samll';
        console.log(dog)
        
        // 增加bowbow()
        dog.bowbow = function(){
            console.log('bow bow !!~~')
        }
        console.log(dog)
        
####     陣列(Array)的宣告及 pop()、push() 使用
    
        // 宣告一個名為 arr 的陣列
        var arr = ['apple', 'orange', 'banana']
        
        // 用索引(index)取'apple'
        arr[0]
        console.log(arr[0])
        
        // 把 arr 陣列最後一個元素回傳並刪除
        arr.pop()
        console.log(arr) // 兩個元素(length = 2)，因最後一個元素'banana'被回傳出來，並且刪除
        
        // 將一個新的元素從 arr 陣列的尾處加入
        arr.push('cat') // 加入'cat'
        console.log(arr) // 三個元素，因陣列尾處被加上'cat'元素(length = 3)
        
####     陣列的基本操作
    
        var arr = [1, 2, 3, 4, 5, 6]
        console.log(arr)

        // 將第一個元素(arr[0])替換為 1000
        arr[0] = 1000
        console.log(arr)

        // 在陣列的第六個元素(arr[5])後插入一個新的元素 12345
        arr[6] = 12345
        console.log(arr)

        // 取得 arr 陣列的最後一個元素，不改變長度
        arr[arr.length - 1]
        console.log(arr[arr.length - 1])
        
####     陣列的基本操作- arr.indexOf()的使用
    
        var arr = ['apple', 'orange', 'banana']

        //indexOf() 取得元素的索引
        console.log(arr.indexOf('orange'))
        
####     陣列的基本操作- 切片 slice()的使用
        
        var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
        arr.slice(2,4) // 'c' 、 'd'
        console.log(arr.slice(2,4)) // 含頭不含尾，即為 arr[2] ~ arr[3]
        
####     陣列進階方法- map() 對陣列內元素進行相同的操作
    
        var dogs = ['Boy 1', 'Boy 2', 'Girl 1', 'Girl 2']
        var result = dogs.map(function(dog){ // 將dogs裡的每個元素後面都加上'is good'字串
            return  dog + 'is good'
        })
        console.log(result)
        
####     陣列進階方法-自己寫 map()，以for迴圈實作，效果同上(優先學習這邊!!，含有資料結構概念)
    
        var dogs = ['Boy 1', 'Boy 2', 'Girl 1', 'Girl 2']
        
        function map2(dogs) { // dogs為放入map2()的參數，即為需要操作之對象
            var result = []
            for(var i = 0; i < dogs.length; i++){ // 使用for迴圈迭代dogs陣列
                var str = dogs[i] + ' is good'
                console.log(str)
                result.push(str)
            }
            return result
        }

        var my_dogs = map2(dogs)
    
####     陣列進階方法-forEach()，以及迭代方法比較
    
        // 宣告一個名為array1的陣列
        const array1 = ['a', 'b', 'c']

        // 以forEach()實作，不改變陣列內容
        let forEachResult = array1.forEach(function(element) {
            console.log(element + ' is good')
        })
        console.log(array1)

        // 以map()實作，會改變陣列內容
        let mapResult = array1.map(function(element) {
            return element + ' is good'
        })
        console.log(mapResult)

        // 以for迴圈實作，不改變陣列內容
        for(var i = 0; i < array1.length; i++){
            console.log(array1[i] + ' is good')
        }
        console.log(array1)
        
####     filter()-過濾器
    
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        var new_arr = arr.filter(function(element) {
        
            // 回傳arr陣列中數字介於3~5的值，有等號，所以範圍是含頭含尾
            return (element >= 3 && element<=5)
        })
        console.log(new_arr)


        var arr1 = [
            {name: 'Tom', age:20},
            {name: 'Mary', age:30},
            {name: 'Bill', age:50},
        ]
        var new_arr1 = arr1.filter(function(person) {
            return person.age < 50 // 回傳年齡小於50的所有資料
            return person.name === 'Tom' // 回傳名字等於Tom的所有資料
            // 兩項return擇一進行實驗
        })
        console.log(new_arr1)
        
####     find() VS filter()
    
        const arr1 = [5, 12, 12, 8, 130, 44] // 兩個12為實驗對象

        let found = arr1.find(function(number) {
            return number === 12
        })
        console.log(found) // 只會有一個12，且是陣列中第一個12(arr1[1])

        let filterFound = arr1.filter(function(number) {
            return number === 12
        })
        console.log(filterFound) //返回一個陣列[12, 12]
        
####     Array.prototype實際操作 **（需詳細了解規則再去做需要之改寫）**
        
        Array.prototype.dog = 'bow' // 新增一個 Array.prototype 屬性 dog，值為 'bow'
        var arr = [] // 宣告一個空陣列以便呼叫dog屬性
        console.log(arr.dog)
        
####     reduce()實際操作
    
        var numbers = [1, 3, 4, 5, 6, 7]
        
        // 以 forEach() 進行相同操作
        var count = 0 // 同等於底下的sum，為暫存目前加總值
        
        // 利用forEach() 對 numbers陣列的所有元素進行迭代
        var all_num = numbers.forEach(function(num) {
            count += num
        })
        console.log(count)

        // sum 為目前暫存加總值，current 為目前number中被操作的元素，即為陣列中的數字
        var result = numbers.reduce(function(sum, current) { 
            sum += current // 進行加總動作
            return sum // 回傳給reduce函式，用意是告訴它現在操作(加總)到多少
        }, 0) // 0為sum的預設值，通常這類計數器都由0開始
        console.log(result)
        
####     宣告字元(var, let, const)作用域實作比較
    
        // 作用域的改變
        // var => function
        // let, const => {}

        // ex1: for 迴圈 - var 宣告
        var i = 0;
        for(var i = 0; i < 10; i++){
            console.log('迴圈跑第 ' + i + '次')
        }
        // 迴圈裡面的 i 汙染到外面的 i
        console.log(i) // 10

        // ex2: for 迴圈 - let 宣告
        let i = 0;
        for(let i = 0; i <10; i++){
            console.log('迴圈跑第 ' + i + '次') 
        }
        // 迴圈裡面的 i 沒有汙染到外面的 i，因為迴圈內的 i 作用域僅在迴圈內
        console.log(i) // 0
        
        // ex3: if...else... - var 宣告
        var x = 1
        if(x === 1){
            var x = 5;
        }else{
            var x = 10;
        }
        // 原理同上
        console.log(x) // 5 

        // ex4: if...else... - let 宣告
        let x = 1
        if(x === 1){
            let x = 5;
        }else{
            let x = 10;
        }
        // 原理同上
        console.log(x) // 1

        // ex5: IIFE 立即函式
        (function() {
            var x = 1;
        })();
        let x = 3;
        // 原理同上
        console.log(x);
        
        // ex6: const 常數變數宣告
        const dog = 'Peter'
        // dog = 'Mary' // 主控台會拋錯，錯誤原因：不能再次對dog這個名稱進行操作
        console.log(dog)

        // ex7: const 常數物件宣告(常數定義物件的時候其實是定義物件的位置)
        const person = {
            name: 'huang',
            age: 20,
        }
        person['name'] = 'Jason'
        console.log(person) // name: 'Jason', age: 20
        
        // 物件內屬性仍可改變，但 person 物件已不能再次定義物件位置
        
####     解構賦值(Destructuring Assignment)
        
        // 正常賦值
        let a = 1
        let b = 2
        let c = 3
        console.log(a, b, c)

        // 陣列解構賦值
        let [a, b, c] = [1, 2, 3]
        console.log(a, b, c)
        
        // 物件解構賦值
        let {a, b } = {a: 1111, b: 2222} // ES6(縮寫表示方式)
        let {a: a , b: b } = {a: 1111, b: 2222} // 完整表達式
        console.log(a, b) // 1111 2222
        
####     iterator迭代協議
    
        //字串實作
        var myStr = 'hello'
        var iterator = myStr[Symbol.iterator]()
        console.log(iterator.next()) // h
        console.log(iterator.next()) // e
        console.log(iterator.next()) // l
        console.log(iterator.next()) // l
        console.log(iterator.next()) // 0
        console.log(iterator.next()) // undefined

        // 陣列實作
        var myArray = [1, 2, 3, 4, 5, 6, 7]
        var arrayiterator = myArray[Symbol.iterator]()
        console.log(arrayiterator.next()) // 1
        console.log(arrayiterator.next()) // 2
        console.log(arrayiterator.next()) // 3
        console.log(arrayiterator.next()) // 4
        console.log(arrayiterator.next()) // 5
        console.log(arrayiterator.next()) // 6
        console.log(arrayiterator.next()) // 7
        console.log(arrayiterator.next()) // undefined
        
####     for..of & for...in
    
        // for...of
        const array1 = ['a', 'b', 'c'];
        for(const element of array1) {
            console.log(element);
        }

        // for..in
        var object = { 
            a: 1, 
            b: 2, 
            c: 3 
        };
        function show_props(obj, objName) { // obj -> 放入函式的物件(object)
            var result = "";
            for (var prop in obj) { // prop -> key值

                // 因物件是dictonary形式(鍵值對) -> key: value，所以呼叫其屬性值需要以objname['keyname']的方式進行調用
                result += objName + "." + prop + " = " + obj[prop] + "\n";
            }
            return result;
        }
        alert(
            show_props(object, "object"),
        ); // object.a=1 object.b=2 object.c=3
        
####     擴展運算子 Spread Operator
    
        // 使用在陣列上
        let arr1 = [1, 2, 3, 4, 5]
        let arr2 = [6, 7, 8, 9]
        console.log(...arr1) // 依序將 arr1 中元素印出
        // 以Math.min()為例 -> 找出最小值
        var a = Math.min(arr1)
        console.log(a) //NaN -> Not a number ，因為此方法對象是一些值，而不是陣列
        var b = Math.min(...arr1) // ...arr1 -> 1, 2, 3, 4, 5
        console.log(b)

        // 陣列連接
        let arr3 = [1, 2, 3, 4, 5]
        let arr4 = [5, 6, 7, 8, 9]
        var arr5 = [...arr3, ...arr4] // 等同於 var arr5 = arr3.concat(arr4)
        console.log(arr5)

        // 使用在物件上(須注意)
        let obj1 = {
            a: 1,
            b: 2,
            c: 3
        }
        let obj2 = {
            c: 5,
            d: 6
        }
        let result = {...obj1, ...obj2}
        console.log(result) // {a: 1, b: 2, c: 5, d: 6}，會取代掉相同屬性
        
####     箭頭函式(Arrow Function)
    
        const function1 = x => x + 1
        console.log(function1(1)) // 2，沒有大括號，預設有回傳值
        const function2 = x => {x + 1} // undefined，有大括號，沒有回傳值
        console.log(function2(1))

        // this 綁定的對象，不再是function本身
        function greet() {
            let reply = `Hi, ${this.person}`
            console.log(reply)
        }
        var obj = {
            person: 'Bill'
        }
        greet.call(obj)

        // 1.一般函式
        const obj1 = {
            a: 1,
            b: 2
        }
        function myFunction1(){
            // 以setTimeout()為例
            console.log('output 1 ', this.a) // 1
            setTimeout(function(){ // function是作用域的隔閡
                console.log('output 2 ', this.a) // undefined
            }, 1000)
        }
        myFunction1.call(obj1)

        // 2.箭頭函式
        const obj2 = {
            a: 1,
            b: 2
        }
        function myFunction2(){
            console.log('output 1 ', this.a) // 1
            setTimeout( () => { // 箭頭函式不會有作用域的隔閡，因此不會影像到this
                console.log('output 2 ', this.a) // 1
            }, 1000)
        }
        myFunction2.call(obj2)
####     fetch()，執行非同步請求 -> Promise語句
        
        const getNewDog = () =>{
            // fetch 跟別人的伺服器拿東西。
            // 支援promise，promise是一個方便的語法，可以用來執行一些非同步的環境。     
            fetch('https://dog.ceo/api/breeds/image/random') // 指定網站進行請求
                // 依你的請求並透過.json()方法向目標網址要求資料
                .then(response => response.json()) 
                .then(json => { // json物件
                    console.log(json)
                    dogImageDiv.innerHTML = `<img src='${json.message}'>` // 使用樣板字樣值將獲取到的message嵌入HTML碼
            })
            console.log('得到狗狗!')
        }
                
###     **二(文字筆記).**

JavaScript不分浮點數&整數

單、雙引號不得混用

ES6可以用`‵ ‵`符號進行宣告(1旁邊波浪符號鍵)

變數未指派值 = 未定義(undefined)

參與運算之符號 => 運算子/運算符

參與運算之數值 => 運算元

「 **=** 」  賦值運算子

「 **==** 」 比較運算子

「 **===** 」 (嚴謹)絕對比較運算子(多比較資料型態) => 常用

「 **&&** 」 AND 都真才真

「 **| |** 」 OR 都假才假

「 **| |=** 」 預設值 變數沒有值就給預設數值，有則直接返回該值

「 **!==** 」不等於

「 (運算式) ? (true執行敘述) : (false執行敘述) 」 -> 三元運算子

DRY => don't repeat yourself

**表達式**(Expression) -> **會**回傳值

**陳述句**(Statement) -> **不會**回傳值

**一個Statement(陳述句)裡面可能會透過一些Expression(表達式)來得到一些值**

函式**陳述式**(Function Statement) ->　可以在函數**宣告前呼叫它**

函式**表達式**(Function Expression)　-> **只能在函數宣告後進行呼叫**

JavaScript **有變數提升 (Hoisting)** 的特性

在函式內使用**let**、 **var**...來保護變數不受影響

**window** -> **瀏覽器的根物件**，變數可用window來存取 ex: var y = 1，window.y -> 1

**node.js** 根物件 -> **global**

**JavaScript** 是可以把函數做為參數傳遞；Java使用**Lambda**特性去實現相同效果；C 有 **function pointer** 的結構也可以達到同樣的效果

匿名函式使用時機 -> 當作參數傳遞進去的函式只需使用一次，即為在其他程式區塊不會使用它(函式)，所以不用特別命名，稱為「匿名」

**console.log** 與 **console.log()** 之差異在於，前者為執行前，所以顯示其為函數;後者則是執行後(調用函數後)，在括弧內輸入參數(想顯示的值)，顯示結果為自定義參數，即為輸入值

**立即函式(Immediately Invoked Functions Expressions):**
1. 可以立即呼叫的函示表達式
2. 會回傳值(因有表達式之特性)
3. 使用函式表達式回傳後立即執行

使用let進行變數宣告前，**變數不得存取**，會出現 **Uncaught ReferenceError**

變數提升(Hoisting)詳細範例過程 -> 19.html

**nodefined** -> 從未宣告

undefined(console.log(x)，var x = 10，console.log(x) -> **第一個console.log(x)會等於undefined**，在賦予值之後，會**有值印出「第二個console.log(x)」**，即為有宣告，但未賦予值) -> 有宣告，未賦值

**let** -> 宣告前不得存取，宣告後不得再次宣告

**JavaScript中的物件:**
1. 用大括號宣告
2. 一個鍵(key)對應一個值(value)
3. 值又稱為屬性(attribute)
4. 物件內屬性可以是正常(基礎)型別(如:number, string, boolean, null, undefined, symbol「符號」)、陣列(array)，也可以是function(函式)

**陣列(Array)是一種資料結構:**
1. 物件是鍵值(key, value)的資料結構
2. 陣列是依照索引(index)排序的資料結構

**陣列詳細操作 網址**:https://www.oxxostudio.tw/articles/201908/js-array.html#array_shift

**prototype** -> 可讓陣列這個資料結構有新的屬性或方法可以呼叫，ex:每一個陣列都會繼承這個 **map()** **（平常如無特殊需求不要隨意改寫Array.prototype）**

MDN -> 有詳細教學

**function** 作為作用域是 **JavaScript** 的基本特性

**環境不符合** or **有使用第三方套件**的話，使用 **webpack** 來編譯

**find()** 與 **filter()** 的比較 -> 前者是返回符合條件的第一筆資料;後者則是返回符合條件的所有資料，資料類型可能會是陣列

**除了Chrome確定支援ES6，大部分瀏覽器不支援ES6，如有需要，可用babel將 ES6 -> ES5**

**const(常數)定義後不會被改變**

**迭代協議** -> https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Iteration_protocols

**for...of(迭代可迭代的物件，需實作iterator)，ES6新的標準** -> https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of

**for...in(直接迭代可列舉的屬性)** -> https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in

**擴展運算子 Spread Operator(...array):**
1. 快速將好幾個參數傳入function
2. 連接陣列
3. 連接物件(如果兩個或多個物件有相同屬性，須注意會被覆蓋)

**文件物件模型(DOM, Document Object Model):**
1. HTML 須遵守 W3C 的規範
2. 遵守 W3C 的 HTML 可以被解析成 DOM 樹(tree)
3. 對應物件為 doucument -> window.document

**HTML 樹狀(tree)結構**
![image](https://hackmd.io/_uploads/SySZ1Rqt6.png)


**HTML 文件物件模型(DOM)結構**  (每一個元素都是一個物件)
![image](https://hackmd.io/_uploads/BJR3JAct6.png)

**應用程式編程介面(API, Application Programming Interface):**
1. A, Application：應用程式本身
2. P, Programming：透過編程行為產出與應用程式交談的程式
3. I, Interface：透過程式產生的介面，使人能與程式交流
**總結：透過寫程式的方式與應用程式溝通**

DOM Document詳細操作 -> https://www.w3schools.com/js/js_htmldom_document.asp

**瀏覽器物件模型(BOM, Browser Object Model):**
1. B, Browser：代表整個瀏覽器
2. O, Object：代表物件，即為瀏覽器的每個元素
3. M, Model： 代表模型，完整的瀏覽器結構所形成的模型
4. 對應物件為 window(根物件，不用特別區宣告，且接下來宣告的東西都會依附在『根物件』上面)


window 樹狀結構圖:
![image](https://hackmd.io/_uploads/HyqxcAqK6.png)

**以window根物件中的location API為例：**
window.location.href -> 可以取得當前瀏覽網頁之網址

**以history API為例：**
window.history.back() -> 回到上一個瀏覽頁面
window.history.go(1) -> 導向下一頁，輸入參數用來控制導向之頁面
window.history.go(-1) -> 回到上一頁

JavaScript是一個依賴根物件的語言


## 2. 第二周：

###     **一(方法、語法).**
        jQuery("h1") = $("h1") 找到h1標籤的位置
        jQuery("p") = $("p") 找到p標籤的位置
        $(".articles") 找到所有articles類的元素(在css中自己定義的)
        $("#container") 找到所有container容器的元素
        $('#destinations li') 找出#destinations底下的所有<li>標籤
        $(this).parent('.vacation') 找出這個標籤的父節點，括號內若增加參數，即為尋找這個標籤的父節點上的vacation類別(可能會返回很多個vacation類別)
        $(this).closest('.vacation') 透過遍歷DOM的方式來找到vacation類別的父節點，並可加以操作(解決上面的問題)
        .slideDown() 顯示
        .slideUp() 隱藏
        .slideToggle() 輪流觸發
        .fadeIn() 淡入
        .fadeOut() 淡出
        .fadeToggle() 輪流觸發
        
        .show() 顯示 // 用來處理display: none、display: block
        .hide() 隱藏
        
        .addClass() 目標新增樣式，括弧內參數為要新增之css樣式
        .removeClass() 目標移除樣式
        .toggleClass() 目標可新增可移除樣式
        
1. 元素選擇器

        // Html:
        <ul id="destinations">
            <li>Rome</li>
            <li>
                <ul id="france">
                    <li>Paris</li>
                </ul>
            </li>
            <li class="promo">Rio</li>
        </ul>
        
        //script:
        <script>
            $(document).ready(function(){
                $("#destinations > li"); // 選擇#destinations底下第一層<li>標籤
                $(".promo, #france"); // 逗號可選擇多個元素
                $("#destinations li:first") // 偽選擇器，#destinations底下第一個<li>標籤
            })
        </script>
        
2. 插入子節點
        
        // Html:
        <li class="vacation" style=" list-style-type: none; margin-left: 200px;">
            <h2>Hawaiian Vacation</h2>
            <button>Get Price</button>
        </li>
        
        // script:
        <script>
            $(document).ready(function(){
                var price = $('<p>From $399.99</p>') // 宣告一個新的<p>標籤(節點)
                // $('.vacation').before(price) // vacation 類別的前面
                // price.insertBefore($('.vacation')) // 同上
                
                // $('.vacation').after(price) // vacation 類別的後面
                // price.insertAfter($('.vacation')) // 同上
                
                // $('.vacation').prepend(price) // vacation 類別中的第一個
                // price.prependTo($('.vacation')) // 同上
                
                // $('.vacation').append(price) // vacation 類別中的最後一個
                // price.appendTo($('.vacation')) // 同上
                
                // $('button').remove() // 移除button那個位置的節點
            })
        </script>
        
3. 監聽事件(滑鼠點擊)

        // Html:
        <li class="vacation" style=" list-style-type: none; margin-left: 200px;">
            <h2>Hawaiian Vacation</h2>
            <button>Get Price</button>
        </li>
        
        //script:
        <script>
            $(document).ready(function(){
                $('button').on('click', function() { // 監聽事件，滑鼠點擊
                    var price = $('<p>From $399.99</p>')
                    $('.vacation').append(price) // vacation 類別中的最後一個
                    // price.appendTo($('.vacation'))
                    $('.vacation').addClass('p1')
                    $('button').remove() // 移除button那個位置的節點
                })
            })
        </script>
        
4. this的用法
        
        //Html:
        <h1>Vacation Page</h1>
        <div id="vacations">
            <ul style="display: flex;">
                <li class="vacation" style=" list-style-type: none; margin-left: 200px;">
                    <h2>Hawaiian Vacation</h2>
                    <button>Get Price</button>
                </li>

                <li class="vacation" style=" list-style-type: none; margin-left: 200px;">
                    <h2>Orlando</h2>
                    <button>Get Price</button>
                </li>

                <li class="vacation" style=" list-style-type: none; margin-left: 200px;">
                    <h2>Visit Japan</h2>
                    <button>Get Price</button>
                </li>
            </ul>
        </div>
        
        // script
        <script>
            $(document).ready(function(){
                $('button').on('click', function() { // 監聽事件，滑鼠點擊
                    var price = $('<p class="p1">From $399.99</p>')
                    $(this).closest('.vacation').append(price) // 你點哪裡就作用哪裡$(this)。
                    $(this).remove() // 移除button那個位置的節點
                })
            })
        </script>
###     **二(文字筆記).**
jQuery 可以做哪些事:
1. 找到HTML頁面中的元素
2. 改變HTML內容
3. 根據用戶的操作作出反饋 ex:按下按鈕
4. 在頁面中使用動畫效果
5. 與網頁交談
6. 如果不想刷新頁面而改變頁面內容，那就可以使用jQuery

class -> "."

id -> "#"

data-tag -> HTML5的特性

滑鼠監聽事件種類:
1. click -> 單擊滑鼠
2. dblclick -> 雙擊滑鼠
3. focusin ->
4. focusout ->
5. mouseup ->
6. mousedown ->
7. mousemove ->
8. mouseout ->
9. mouseover ->
10. mouseleave ->
11. mouseenter -> 當滑鼠進入元素區域內，即可觸發

鍵盤監聽事件種類:
1. keypress
2. keydown
3. keyup -> 敲完一個鍵

表單監聽事件種類:
1. focus
2. blur
3. select
4. submit
5. change

瀏覽器前綴:
![image](https://hackmd.io/_uploads/rJNo_El5p.png)

連接網路API -> CDN，也可以下載到本地端做引用

npm是Node.js預設的、用JavaScript編寫的軟體套件管理系統。

## 3. 第三周：

###     **一(方法、語法).**
    
###     **二(文字筆記).**

## 4. 第四周：

###     **一(方法、語法).**
    
###     **二(文字筆記).**
