> 如果有記憶吐司就好了...
# JS 學習筆記
## 陣列
宣告一個陣列的方式用[]包資料,每筆資料用逗號隔開
```=
let colors = ["red","blue","black"];
```
讀取陣列裡面的資料,陣列的第一筆從0計算
```=
console.log(colors[0]);
// 變數colors裡面的陣列第0筆,回傳值為red。
```
### push()
將資料加入到陣列裡面的最後一筆,
使用時機:排名搶頭香
```=
colors.push("pink");
```
### unshift()
將資料加入到陣列裡面的第一筆
使用時機:最新的放最前面ex:新聞
```=
colors.unshift("pink");
```
### pop()
將陣列內的最後一筆資料刪除
```=
colors.pop();
```
### shift()
將陣列內的第一筆資料刪除
```=
colors.shift();
```
### splice(索引位置,數量)
將陣列內的其中一筆或是一個範圍內的資料刪除
使用時機:待辦事項做完要刪除的時候
```=
let colors = ["red","blue","black"];
colors.splice(1,2);
// 括弧內的1為陣列內的第1筆blue開始,括弧內的2為從blue開始刪除2筆資料,所以將刪除blue及black共兩筆資料
```
### concat()
concat 是用於串接兩個陣列,串接的結果會透過回傳值取得,並不會套用至原有的陣列
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];
let newArray = array.concat(["政憲","羚貽"]);
console.log(newArray);
// newArray回傳 ['小明', '杰倫', '漂亮阿姨', '小美', '政憲', '羚貽']
// array 依然是 ["小明", "杰倫", "漂亮阿姨", "小美"]
```
### include()
include 可以用來檢查陣列中是否包含特定值,結果會透過回傳的方式取得
```=
et array = ["小明","杰倫","漂亮阿姨","小美"];
console.log(array.includes('漂亮阿姨')); // true
console.log(array.includes('阿明')); // false
```
### indexOf()
與 include() 運作上相當類似,僅不過 include() 是回傳 true、false,而 indexOf 則是回傳該值的索引位置
```=
console.log(array.indexOf('漂亮阿姨')); // 2
console.log(array.indexOf('阿明')); // -1
// 當值如果不存在於陣列中,則會回傳 -1
```
### join()
可以將陣列中的值轉變為字串,並且加入特定字元作為值相間的符號
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];
console.log(array.join(', ')); // 小明, 杰倫, 漂亮阿姨, 小美
console.log(array.join('/')); // 小明/杰倫/漂亮阿姨/小美
```
簡單的語法,但是搭配 ES6 中的 Template literal 可以用極短的程式碼組合出複雜的字串結構
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];
let newHTML = `<ul>${ array.map((item)=> `
<li>${item}</li>`).join(' ')}
</ul>`;
console.log(newHTML);
// 回傳
<ul>
<li>小明</li>
<li>杰倫</li>
<li>漂亮阿姨</li>
<li>小美</li>
</ul>
```
## 物件
宣告一個物件,用 **{}** 包資料,裡面可建立多筆屬性,屬性名稱放左邊,用冒號做賦予,右邊則放入值,物件內的每筆屬性用逗號隔開,每筆物件的最後一筆屬性可以不加逗號。
```=
let teamA ={
name:"Jasper",
age:32,
height:168
};
```
### 如何讀取物件內屬性的值
1. 用 **.** 來指定要讀取哪一筆屬性的值
```=
console.log(teamA.name);
// 讀取變數teamA物件內屬性為name的值,回傳為Jasper
```
2. 用 **[]** 裡面加單/雙引號來取指定屬性的值
使用時機:不允許讀取的狀態,遇到特殊字元的時候ex:屬性開頭為數字
```=
console.log(teamA['name']);// 取值的方式
let teamA ={
name:"Jasper",
age:32,
height:168
};
let thatName = "name";
// 宣告一個新的變數並賦予物件內name屬性來取值
console.log(teamA.thatName);
// 用.來取值,僅會幫您找到teamA物件裡面符合的屬性,所以沒有在teamA內找到符合thatName的屬性,回傳undefined
console.log(teamA[thatName]);
// 用[]來取值,除了幫您在teamA物件內找尋之外,還會在記憶體內找尋變數是否有被賦予符合的屬性,回傳"Jasper"
```
若是用[]取物件內的屬性,需加單/雙引號
```=
console.log(teamA["name"]);
```
### 如何新增物件內的屬性及資料
用 **.** 來新增屬性並用等於賦予值
```=
teamA.weight = 57;
// 於物件teamA裡面新增weight的名稱並賦予值57
```
用 **[]** 包單/雙引號來新增屬性或特殊字元的屬性ex:數字開頭的屬性名稱
```=
teamA["0"] = false;
// 於物件teamA裡面新增屬性名稱為0並賦予值false
```
### 如何變更物件內的資料
用 **=** 重新賦予值,或是依照語意運算本來的屬性
```=
// 今天量體重發現少了一公斤
teamA.weight = 56;
or
teamA.weight -= 1;
```
## 函式 function
宣告一個函式名稱,後面 **()** 為參數, **{}** 內為執行後要做的動作,用 **morningAction()** 來呼叫函式
```=
function morningAction(){
console.log('起床');
console.log('刷牙');
console.log('洗臉');
console.log('出門');
};
morningAction(); //執行函式
// 回傳 起床、刷牙、洗臉、出門
```
### 函式內也可以執行函式
宣告另一個函式放入要呼叫的函示內
```=
function morningAction(){
console.log('起床');
cleanHead();
console.log('出門');
};
function cleanHead(){
console.log('刷牙');
console.log('洗臉');
};
morningAction(); //執行函式
// 回傳 起床、刷牙、洗臉、出門
```
### 函式參數介紹
函式的()內放入參數,執行函式時可帶入參數的值
```=
function number(num){
console.log(num);
};
number(1);
// 回傳 1
```
### 使用參數相加
**()** 內可輸入多個參數,須用 **,** 隔開
```=
function add(num,num2){
console.log(`總共${num+num2}元`);
};
add(1,2);
// 回傳總共3元
```
### 參數的值只存在在{}內
```=
function add(num,num2){
console.log(num,num2); //回傳1、2
};
add(1,2);
console.log(num); // 回傳錯誤
```
### return回傳至指定的地方
若沒有用return,即使宣告一個變數並賦予函式給予參數,雖然函式會執行帶入的參數,但是並不會將結果回傳至變數,僅留在 **{}** 內
```=
function testScore(mathScore,englishScore){
console.log(mathScore+englishScore);
};// 回傳170
let JasperTotalScore = testScore(90,80);
console.log(JasperTotalScore);
// 回傳unfefined
```
宣告一個變數並賦予函式給予參數,執行函式後使用return將 **{}** 內執行的結果,回傳至被賦予的函式
```=
function testScore(mathScore,englishScore){
return mathScore + englishScore;
};
let JasperTotalScore = testScore(90,80);
console.log(`Jasper總分為${JasperTotalScore}分`);
// 回傳Jasper總分為170分
```
## DOM 選取網頁元素
### querySelector選擇器
只會選擇網頁內最前面第一個dom。
```htmlembedded=
// html環境
<p>我被 el 選到了</p>
<p>我沒有被選到</p>
```
```js=
let el = document.querySelector("p")
//只會回傳第一個符合選取條件的元素
```
可以選取帶有 id 或 class 的元素
```htmlembedded=
// html環境
<body>
<p id="targetID"> 我被 elementID 選到了</p>
<p class="targetClass">我被 elementClass 選到了</p>
</body>
```
```=
let elementID = document.querySelector("#targetID");
let elementClass = document.querySelector(".targetClass");
// 宣告一個變數,用選擇器選取html的.main
```
可以用類似 CSS 的撰寫方式選取
```htmlembedded=
// html環境
<div id="targetID">
<p>我被 elementID 選取到了</p>
</div>
<!-- 以下是 span 被選取到 -->
<div class="targetClass">
<p>
<span>我被 elementClass 選取到了</span>
</p>
</div>
```
```js=
let elementID = document.querySelector("#targetID > p");
let elementClass = document.querySelector(".targetClass > p > span");
```
### textcontent
透過 textContent 可以取得 DOM 元素內的 「純文字內容」,HTML 會被忽略 (請注意「純文字內容」有包含換行以及空格)
```htmlembedded=
<div class="targetClass">
<p>取得這個 p 標籤的純文字</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass p");
console.log(targetClass.textContent);
```
結果 (以下為 CodePen console 的結果):

#### 可以透過 textContent 替換 DOM 元素內的內容,需要注意以下幾個重點:
1. 原先的所有內容都會被清空 (包含 HTML 標籤)
2. 新的內容將被瀏覽器解析成「純文字」,不會保留 HTML 標籤的特性。
```htmlembedded=
<!-- 以下的 p 標籤會被清空,替換成純文字 "<h3>修改後的內容</h3>" -->
<div class="targetClass">
<p>替換這個 p 標籤</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
targetClass.textContent = "<h3>修改後的內容</h3>";
```
結果 1:
(網頁渲染出的畫面)

結果 2:
(修改後的 HTML 結構)

#### textContent 可以跟變數混合使用
```htmlembedded=
<div class="targetClass"></div>
```
```js=
let targetClass = document.querySelector(".targetClass");
let score = 100;
targetClass.textContent = `<p>小華的成績為 ${score} 分</p>`
```
結果 1:
(網頁渲染出的畫面)

結果 2:
(修改後的 HTML 結構)

### innerHTML
#### 透過 innerHTML 可以取得 DOM 元素內的「HTML 內容」
```htmlembedded=
<div class="targetClass">
<!-- 註解、換行、空白也包含在內 -->
<p>HTML 標籤的內容也被選取</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
console.log(targetClass.innerHTML);
```
結果 (以下為 Chrome console 的顯示結果):

#### 可以透過 innerHTML 替換 DOM 元素內的 HTML,需要注意以下幾個重點:
1. 原先的所有內容都會被清空
2. 新的內容將被瀏覽器解析成「HTML」,也就是說會保留 HTML 標籤的特性。
```htmlembedded=
<!-- 以下的 p 標籤會被清空 -->
<div class="targetClass">
<p>替換這個 p 標籤</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
targetClass.innerHTML = "<h3>修改後的內容</h3>";
```
結果 1:
(網頁渲染出的畫面)

結果 2:
(修改後的 HTML 結構)

### innerHTML 可以跟變數混合使用
```htmlembedded=
<div class="targetClass"></div>
```
```js=
let targetClass = document.querySelector(".targetClass");
let score = 100;
targetClass.innerHTML = `<p>小華的成績為 ${score} 分</p>`
```
結果 1:
(網頁渲染出的畫面)

結果 2:
(修改後的 HTML 結構)

```js=
main.innerHTML=`<h1>789<h1>`;
// 將html內的.main的架構都可以重新編輯,包含其他標籤
```
### getAttribute, setAttribute 應用
以下連結為 HTML 的屬性列表,可以透過 getAttribute, setAttribute 操作這些屬性。
https://developer.mozilla.org/zh-TW/docs/Web/HTML/Attributes
### getAttribute
#### 使用 getAttribute 可以回傳一個元素上的指定屬性值,語法如下:
```js=
element.getAttribute("屬性名稱");
```
**範例**:
HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
JS
```js=
let element = document.querySelector('#targetId');
console.log(element.getAttribute('id'));
```
結果:

#### 使用 getAttribute 取用屬性時,如果指定的屬性不存在,則會回傳 `null` 或 `""`。
HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
JS
```js=
let element = document.querySelector('#targetId');
console.log(element.getAttribute('name')); // 由於 name 屬性不存在,因此會回傳 null
```
結果:

### setAttribute
#### 可以使用 setAttribute 新增屬性上去,語法如下:
```js=
element.setAttribute("屬性名稱", "屬性值");
```
範例:
HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
CSS
```css=
.colorRed{
color: #FF0000;
}
```
JS
```js=
let element = document.querySelector('#targetId');
element.setAttribute('class', 'colorRed')
```
結果 (以下為網頁渲染畫面):

### querySelectorAll選擇器
回傳的是一個節點列表的陣列
```htmlembedded=
// html環境
<body>
<a herf="#">連結</a>
<a herf="#">連結</a>
</body>
```
```js=
const myLink = document.querySelectorAll('a');
// querySelectorAll回傳的是陣列[a,a]
myLink.setAttrebute[0]("herf","http:yahoo.com.tw")
// 選取陣列第一筆用[0]
myLink.setAttrebute[1]("herf","http:google.com.tw")
// 選取陣列第二筆用[1]
```
### 表單元素的取值方式
```htmlembedded=
// html環境
<body>
<input type="text" class="txt" value="你好嗎">
</body>
```
```js=
const txt = document.querySelector(".txt");
console.log(txt.value);
// 回傳 你好嗎
txt.value = "Hello"
// 將你好嗎改成Hello
```
```htmlembedded=
// html環境
<body>
<select class="list">
<option value="高雄市">高雄市</option>
<option value="台中市">台中市</option>
</select>
</body>
```
```js=
const list = document.querySelector(".list");
// 選取select的list
console.log(list.value);
// 回傳 高雄市
list.value = "台中市";
// 將字面改成台中市
console.log(list.value);
// 回傳 台中市
```
### 事件 event
```htmlembedded=
// html環境
<body>
<input type="button" class="btn" value="點擊">
// 建立一個按鈕
</body>
```
```js=
const btn = document.querySelector(".btn");
btn.addEventListener("click",function(e){
console.log("你已經被點擊了");
})
// 監聽這個按鈕,當被按下時執行特定行為
```
**加法、減法**
```htmlembedded=
// html環境
<body>
<input type="button" class="btn" value="加法">
<input type="button" class="btn2" value="減法">
<h1 class="add">0</h1>
<h1 class="minus">0</h1>
</body>
```
```js=
// 加法
const btn = document.querySelector(".btn");
// 宣告一個變數,賦予選擇上面class="btn"
const title = document.querySelector(".add");
// 宣告一個變數,賦予選擇上面class="add"
let count = 0;
// 宣告一個變數,賦予值為0
btn.addEventListener("click",function(e){
count += 1;
title.textContent = count;
});
// 設立監聽器事件名稱為click
// 當點擊按鈕"加法"
// 則執行函式count += 1
// 並將add的值賦予為count
// 每點擊一次add的值加1
//減法
const btn2 = document.querySelector(".btn2");
const title2 =document.querySelector(".minus");
let count2 = 0;
btn2.addEventListener("click",function(e){
count2 -= 1;
title2.textContent = count2;
})
```
### 透過nodeName了解目前DOM的HTML位置
```htmlembedded=
// html環境
<body>
<input type="button" class="btn" value="點擊">
</body>
```
```js=
const btn = document.querySelector(".btn");
console.log(btn.nodeNamne);
// 回傳 INPUT
```
### etarget搭配nodeName的節點,抓到你預期要做的事
了解到不用每個DOM都綁監聽,可以將外層綁監聽,內層就都會有效果
```htmlembedded=
// html環境
<body>
<ul class="list">
<li>標籤</li>
<li>標籤<input type="button" class="btn" value="按鈕">
</li>
</ul>
</body>
```
```js=
const list = document.querySelector(".list");
list.addEventListener("click",function(e){
console.log(e.target.nodeName);
if(e.target.nodeName == "INPUT"){
console.log("你點到我了");
}
});
// 當點擊到list的範圍則觸發console.log(e.target.nodeName);
// 回傳該範圍的DOM
// 當點擊到INPUT則觸發console.log(e.target.nodeName)+函式
// 回傳INPUT 及 你點到我了
```
### 用preventDefault取消預設觸發的行為
```htmlembedded=
// html環境
<body>
<a href="https:www.yahoo.com.tw/">連結</a>
<h1></h1>
</body>
```
```js=
const myLink = document.querySelector("a");
myLink.addEventListener("click",function(e){
e.preventDefault(); // 停止網頁跳轉過去yahoo
console.log("點擊到我了"); // 回傳 點擊到我了
document.querySelector("h1").textContent = "hello";// 賦予h1內的文字hello
});
```
### data-xxx也可以被選取來使用
除了 `.getAttribute` 以外, `data-xxx` 也可以用 `document.querySelector` 選取,例如:
HTML
```htmlembedded=
<p class="alertMsg" data-title="信箱"></p>
<p class="alertMsg" data-title="密碼"></p>
```
取得 「data-title="信箱"」p 標籤的方式有兩種:
JS
```js=
// 1
document.querySelectorAll('[data-title]')[0];
// 2
document.querySelector("[data-title='信箱']");
```
另外,也可以透過事件綁定來取得 `data-xxx`,例如:
HTML
```htmlembedded=
<p class="alertMsg" data-title="信箱">點我會顯示 dataset</p>
```
JS
```js=
let alertMsg = document.querySelector('.alertMsg');
alertMsg.addEventListener('click', function(e) {
console.log(e.target.dataset.title);
})
```
## forEach
forEach() 是屬於 **「陣列」** 的方法,會將陣列內的每個元素一一傳入,並執行給定的函式一次。 forEach() 內的函式常見會帶有三個參數,以下為用法示例:
```js=
let data = ["a", "b", "c"];
// 參數 item 代表陣列中目前正在被處理的那個元素
// 參數 index 代表陣列中目前正在被處理的那個元素的索引值
// 參數 array 代表被處理的陣列本身,在此為 data
data.forEach(function(item, index, array){
console.log(item, index, array);
})
```
執行結果:

**在 forEach() 函式內用 return 是無效的。除非程式碼有誤,否則並沒有中止 forEach() 的辦法**
```js=
let data = ["a", "b", "c"];
//
data.forEach(function(item, index, array){
console.log(item, index, array);
return; // 程式碼會忽略這個 return
})
```
## 表單取值
### `.value`,`.getAttribute('value')` 觀念
`.value` 取出的值是「字串」
這邊以 input 的 value 取值為例,請觀看以下範例:
HTML
```htmlembedded=
<input type="text" id="targetInput">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');
triggerBtn.addEventListener('click', function(){
console.log(el.value);
console.log(typeof(el.value));
})
```
如果在 input 輸入數字 123 以後點選「觸發按鈕」,可以在 console 中觀察到以下結果:

**因此如果要對表單的「數值」進行運算,請記得要先使用 `parseInt` 做型別轉換。**
範例如下:
HTML
```htmlembedded=
<input type="text" id="targetInput">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');
triggerBtn.addEventListener('click', function(){
let newValue = parseInt(el.value);
console.log(newValue);
console.log(typeof(newValue));
})
```
結果:

### `.value`, `.getAttribute('value')` 的差異
**以下觀念針對常用的「input」這個 HTML 標籤做說明:**
HTML
```htmlembedded=
<input type="text" id="targetInput" value="123">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');
console.log(`el.value: ${el.value}`);
triggerBtn.addEventListener('click', function(){
el.value = "任意填入的值";
console.log(`el.value: ${el.value}`);
})
```
同學的 console 結果應該會呈現如下:

看到這邊,是不是認為 `<input type="text" id="targetInput" value="123">` 這行程式碼的 `value="123"` 應該已經被修改為 `value="任意填入的值"` 了?
>不過,如果我們將程式碼修改如下,並一樣的點選「觸發按鈕」觀察結果:
HTML
```htmlembedded=
<input type="text" id="targetInput" value="123">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');
triggerBtn.addEventListener('click', function(){
el.value = "任意填入的值";
console.log(`el.value: ${el.value}`);
console.log(`el.getAttribute('value'): ${el.getAttribute('value')}`);
})
```
可以發現網頁上 input 欄位「輸入的值」的確已經被更改為 "任意填入的值"

但是 `el.value` 與 `el.getAttribute('value')` 卻是不一樣的,呈現結果如下:

### 由此可知,修改 `el.value` 不等於修改 HTML 標籤的 value 屬性值
* `el.value` 對應的是 input 欄位目前「輸入的值」
* `el.getAttribute('value')` 對應的是 input 欄位的「預設屬性值」
* 修改 `el.value` 並不會影響 input 標籤的 value 預設屬性,使用 `setAttribute()` 才會。
## axios
### axios 的 get 語法可以用來取得遠端伺服器的資料
先在HTML載入axios 的 CDN
```htmlembedded=
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
```
```js=
// 在以下 URL 的部分填入 API 網址
axios.get('URL')
// 如果連接成功,可以用 then() 處理傳回來的值,以下程式碼將回傳結果儲存於 responce。
.then(function (response) {
console.log(response);
});
```
### HTTP 狀態碼
使用 AJAX 比較常遇到、需要了解的狀態碼訊息:
1. **成功回應 (Successful responses, 200–299)**
這區間的狀態碼表示伺服器有成功接收到用戶端要求。以 AJAX 的串接為例,如果回傳的 **status 為 200**,則代表有成功接收到資料。
2. **用戶端錯誤 (Client errors, 400–499)**
這區間的狀態碼表示有錯誤發生,且錯誤來自於「用戶端」。以 AJAX 的串接為例,
* 回傳的 **status 為 400**,表示遠端伺服器接收到無效語法、無法理解請求,因此需要檢查程式碼有無寫錯的地方。
* 回傳的 **status 為 403**, 表示禁止使用,這代表用戶端沒有訪問權限,因此沒辦法成功串接資料。
* 回傳的 **status 404**,表示找不到檔案資料。
3. **伺服器端錯誤 (Server errors, 500–599)**
如果發生狀態碼為 **5xx** 的錯誤,則表示錯誤發生跟「遠端伺服器」有關,此時就需要跟後端工程師進行協調了。
## 將物件包物件轉為陣列包物件小技巧
1. Object.values
```js=
const family = {
liFamily:{
name:'Jasper'
},
huangFamily:{
name:'jeff'
},
changFamily:{
name:'bear'
}
}
console.log(Object.values(family))
// 帶出一筆陣列包三筆物件
取得的是family內的每筆物件的值,放入一個陣列內
```
呈現如下:

```js=
// 搭配forEach
Object.values(family).forEach((item)=>{
console.log(item)
//帶出三筆物件
取得的是family內的每筆物件屬性(不含屬性內的值),放入一個陣列內
})
```
呈現如下:

2. Object.keys
```js=
const family = {
liFamily:{
name:'Jasper'
},
huangFamily:{
name:'jeff'
},
changFamily:{
name:'bear'
}
}
console.log(Object.keys(family))
// 帶出的是family內的屬性
```
呈現如下:

```js=
// 搭配forEach
Object.keys(family).forEach((key)=>{
console.log(family[key])
})
// 一樣可以取得每一筆物件
```
呈現如下:

通常陣列包物件若要取的該陣列內包含幾筆物件,通常可以使用
```js=
const friends = [bear:{...},jasper:{...},jeff:{...}]
console.log(friends.length) // 3
```
若是在物件包物件的資料個是下該如何取得長度呢?
```js=
const family = {
liFamily:{
name:'Jasper'
},
huangFamily:{
name:'jeff'
},
changFamily:{
name:'bear'
}
}
console.log(Object.values(family).length) // 3
console.log(Object.keys(family).length) // 3
```
---
## 如何使用axios撈取資料回來並渲染在畫面上
```htmlembedded=
<div class="container">
<div class="row productList">
</div>
</div>
```
```js=
// 綁定Dom元素
const productList = document.querySelector(".productList");
// 先宣告一個變數,待撈取資料後存入
let productsData;
// 撈取資料的function
function getProducts(){
// 取得資料的網址(通常事後端給的)
let url = "https://livejs-api.hexschool.io/api/livejs/v1/customer/jasper0730/products";
axios.get(url)
// 若成功回傳跑then
.then(function(res){
// 資料存入先前準備好的變數內
productsData = res.data.products;
// 渲染到畫面上的function
render(productsData);
})
// 若失敗回傳跑catch
.catch(function(error){
console.log(error);
})
}
// 渲染到畫面上的function
function render(productsData){
let str=""; // 先宣告一個變數待會拿來暫存資料
用撈回的資料跑forEach,把每一筆物件存入str
productsData.forEach(function(item){
str += `<div class="col-6 mb-3">
<div class="card">
<img src="${item.images}" class="card-img-top productImg" alt="產品圖片">
<div class="card-body">
<h5 class="card-title"><strong>標題:</strong> ${item.title}</h5>
<p class="card-text"><strong>種類:</strong> ${item.category}</p>
<p class="card-text"><strong>原始價格:</strong> ${item.origin_price}</p>
<p class="card-text"><strong>售價:</strong> ${item.price}</p>
<p class="card-text"><strong>描述:</strong> ${item.descrption}</p>
</div>
</div>
</div>`
})
// 先前綁好的Dom元素用innHTML帶入str渲染到畫面上
productList.innerHTML = str
}
// 執行getProducts函式
getProducts();
```
---
## 如何將字串反轉
ex:柏斯賈是我 轉成 我是賈斯柏
範例程式碼如下:
```js=
let name = '柏斯賈是我'
let reverseName = name.split('').reverse.join('');
console.log('name') // 柏斯賈是我
console.log('reverseName') // 我是賈斯柏
```