# JavaScript
###### tags: `Learning`
## 觀念相關
JS 語法寫 var 時,會被定義在 Function 的上一層,類似區域變數的概念,可以用 let 來替代使用
※IE11 以下完全不支援,IE11 可能支援 → [檢查瀏覽器語法支援度](https://caniuse.com/)
---
## Ajax

#### [JSON格式資料回傳寫法](https://www.w3schools.com/js/js_json_stringify.asp)
#### 多個 Ajax 同時進行的方法

#### Ajax 組出 Json 資料給前端接
後端

前端

---
## 用 JS 寫出 Post 方法 ( 組出一個 Form )
Function
```
function post_to_url(path, params, method) {
method = method || "post"; // Set method to post by default, if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
for (var key in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
var aaa = params[key];
form.appendChild(hiddenField);
}
document.body.appendChild(form); // Not entirely sure if this is necessary
form.submit();
}
```
呼叫 Function
```
var data = { examineeID: '@Model.ExamineeInfo.ID', strImage_Base64: image };
post_to_url('@Url.Action("ReportToPDF")', data, "POST");
```
---
## jquery 和 js 寫法比對 ( BS v5 已經停用 jquery )
https://gist.github.com/joyrexus/7307312
---
## bool 判斷
@Json.Encode

---
## 下載檔案導向
window.location.href = url ( 會在當前頁面 )
window.open(url) ( 會開啟新視窗 )
---
## a 標籤,空連結的做法 onclick 中 return false

---
## 神奇的 Cookie
此案例: 把 搜尋頁面的 搜尋條件Json字串 丟到 導向的頁面,讓導向的頁面等等可以把 搜尋條件Json 字串存起來
(後來想想,其實在前端用 JS 把 搜尋條件存到 cookie 就好了= =)

有點有趣,刪除 Cookie 的時候若沒加上 path=/; (沒指定對的 path)
1. 會刪不到
2. 會多一個無效 Cookie
產出一個 頁面相對應的 path 的 無效 Cookie

原本的 Cookie 沒被改到


https://www.runoob.com/js/js-cookies.html
---
## Math.floor v.s Math.round
round = 四捨五入
floor = 去小數點
[可參考](https://www.reddit.com/r/javascript/comments/5vik4j/why_not_always_use_mathround_instead_of_mathfloor/)
* 加碼 Random 用法
```
// returns a random integer from 0 to 9
Math.floor(Math.random() * 10);
// returns a random integer from 1 to 10
Math.floor(Math.random() * 10) + 1;
```
---
## JavaScript 使用forEach() 與 jQuery 使用 each 遍歷陣列時 return false 的區別
1. 使用each()遍歷陣列a,如下:
```
var a=[20,21,22,23,24];
$.each(a, function(index,val) {
console.log('index=' index);
if(index==2){
return false;
}
console.log('val=' val);
});
```
結果如下:
從執行的效果可以看出,return 相當於迴圈中的break,直接結束整個迴圈。
2. 使用forEach()遍歷陣列a,如下:
```
var a=[20,21,22,23,24];
a.forEach(function(val,index){
console.log('index=' index);
if(index==2){
return false;
}
console.log('val=' val);
});
```
結果如下:
從執行的效果可以看出,return 相當於迴圈中的continue,跳出當前迴圈,後面的迴圈遍歷繼續。
我們可以通過自己寫判斷語句結束整個forEach()迴圈,或者使用for()迴圈遍歷。
[資料來源](https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/261335/)
---
## jquery根據表格中一個欄位(td) 獲得同一列其他欄位(td)資料
### 實作
#### HTML

#### JS
```
function Delete(elem_btn) {
var row = $(elem_btn).parent().parent()
alert('You clicked on Employee Name is ' + row.find("td").eq(1).html() + ' Row.');
//another example row.find("td#categoryName").eq(0).html();
}
```
解釋: $(elem_btn).parent().parent().find("td").eq(1).html()
刪除按鈕的 parent => td 的 parent => tr,找出 tr 底下所有的 td,取 Index 第 1 筆
但是這樣寫維護性比較差,我可能會 find 依照 class 找,然後 eq(0),這樣未來在調整的時候錯誤率比較低...(?)↓↓↓

[參考來源-用JQuery 選擇Table某tr元素](http://m.blueshop.com.tw/Thread.aspx?tbfumsubcde=BRD20130306143330PN3)
[參考來源-使用jquery获取table选中行的其他列的值](https://blog.csdn.net/Liyatao_BeiJing/article/details/49995725)
---
## 判斷是否存在的寫法,超懶

建議還是乖乖寫 Length....
---
## 依照 Class 名稱取得元素 (element)
> var elements = document.getElementsByClassName(names);
or
> var elements = rootElement.getElementsByClassName(names);
以下範例,Onclick 後取得其 class 名為 "card-body" 的子元素的 innerText:
Script
```
$(".card").click(function () {
console.log(this.getElementsByClassName('card-body')[0].innerText)
});
```
Html
```
<div class="card text-white bg-primary card-center card-3D" data-toggle="modal" data-target="#modalLogin">
<div class="card-header">
<img class="imgProfilePicture" src="./Images/UserPicture(Test).jpg">
</div>
<div class="card-body">
輝夜
</div>
</div>
```
---
## 日期格式相關 new Date(value)
### 取得日期
#### getFullYear() 取得年份
> dt.getFullYear(); // 2020
#### getMonth() 取得月份,從 0 開始算起
一月 = 0, 二月 = 1, 三月 = 2, 四月 = 3, 五月 = 4, 六月 = 5, 七月 = 6...十月 = 9, 十一月 = 10, 十二月 = 11
##### 取得月份數字
> document.write( (dt.getMonth() + 1) )
##### 取得月份文字
建立一個 month 陣列物件用來存放相對映於索引編號的月份名稱。
>
> var dt = new Date();
> var month = new Array(12);
> month[0] = "一月";
> month[1] = "二月";
> month[2] = "三月";
> month[3] = "四月";
> month[4] = "五月";
> month[5] = "六月";
> month[6] = "七月";
> month[7] = "八月";
> month[8] = "九月";
> month[9] = "十月";
> month[10] = "十一月";
> month[11] = "十二月";
> document.write("本月份 = " + month[dt.getMonth()]);
>
#### getDate() 取得日(天) 1~31
> document.write(dt.getDate()); //28
#### getDay() 取得星期
星期日 = 0, 星期一 = 1, 星期二 = 2, 星期三 = 3, 星期四 = 4,星期五 = 5, 星期六 = 6
> document.write(dt.getDay());
### 取得時間
#### getHours() 取得時數 0~23 台北標準時間+8
> document.write(dt.getHours());
#### getUTCHours() 取得(國際標準時間)時數 0~23
> document.write(dt.getUTCHours()); //UTC 表示 Coordinated Universal Time 國際標準時間
#### getMinutes() 取得分鐘 0~59
> document.write(dt.getMinutes());
#### getSeconds() 取得秒數 0~59
> document.write(dt.getSeconds());
#### getMilliseconds() 取得毫秒數 0~999
> document.write(dt.getMilliseconds());
#### getTime() 取得時間 (由 1970年1月1日零時零分計起到目前時間) 單位:(毫秒)
> document.write(dt.getTime());// 1590647585262
#### getTimezoneOffset() 取得 GMT 減去本地時間的值 單位:(分鐘)
> document.write(dt.getTimezoneOffset()); //數值會受日光節約時間之影響。 result = 480
### 設定時間
#### setFullYear() 設置年份 (四位數字)
> dt.setFullYear(2008)
#### setMonth() 設置月份 0~11
> dt.setMonth(5)
#### setDate() 設置日(天) 1~31
> dt.setDate(3)
#### setHours() 設置時數 0~23
> dt.setHours(10);
#### setMinutes() 設置分鐘 0~59
> dt.setMinutes(30);
#### setSeconds() 設置秒數 0~59
> dt.setSeconds(12);
#### setMilliseconds() 設置毫秒數 0~999
> dt.setMilliseconds(280);
[參考-JavaScript Date() 日期與時間](http://www.eion.com.tw/Blogger/?Pid=1148)
---
## Onclick... 取得觸發事件的元素(element)
#### event.target

---
## 取得 Select 選單的 text & value
Html
```
<select id="ddlMailTemplateList" class="form-control">
<option></option>
<option value="NoPay">未繳費範本</option>
<option value="BeforeTheStart">行前通知範本</option>
</select>
```
Script
```
$("#ddlMailTemplateList").change(function (e) {
// 選擇的選項字串
var text = e.target.options[e.target.selectedIndex].text;
// 選擇的選項植
var value = e.target.value
})
```
---
## CheckBox 勾選控制 ( 取得某元素的 Child )
Html
```
<div class="col-md-9 col-sm-9 col-lg-9">
<button type="button" id="btnCheckAllMember" class="btn btn-warning" style="margin-right:5px">勾選全部</button>
<button type="button" id="btnCheckNotPayMember" class="btn btn-warning" style="margin-right:5px">勾選未繳費</button>
<button type="button" id="btnCancalCheckAllMember" class="btn btn-danger" style="margin-right:5px">取消全部</button>
</div>
<div class="col-md-9 col-sm-9 col-lg-9" style="padding:15px">
<div class="row">
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
<i class="fas fa-exclamation-circle fa-lg" title="未繳費"></i>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
<div class="chkGroup">
<input type="checkbox" id="member_1" value="memberId" title="moira_han@mail.csf.org.tw" />
<label class="lblCheckbox" for="member_1" title="moira_han@mail.csf.org.tw">Moira</label>
</div>
</div>
</div>
```
Script
```
$(function () {
// Jquery 按鈕觸發 click 事件
$("#btnCheckAllMember").click(function (e) {
// 先全部取消勾選
ClearAllCheckStatus();
// 找出 class 維 chkGroup 的元素們
var allMemberChkGroup = document.body.getElementsByClassName("chkGroup");
// 迴圈找個別下的 checkBox 並勾選
$.each(allMemberChkGroup, function (i, item) {
item.querySelector("input[type='checkbox']").checked = true;
})
})
$("#btnCheckNotPayMember").click(function (e) {
// 先全部取消勾選
ClearAllCheckStatus();
var allMemberChkGroup = document.body.getElementsByClassName("chkGroup");
$.each(allMemberChkGroup, function (i, item) {
// 判斷是否未繳費
if (item.getAttribute("memberStatus") == "NotPay") {
item.querySelector("input[type='checkbox']").checked = true;
}
})
})
$("#btnCancalCheckAllMember").click(function (e) {
// 全部取消勾選
var allMemberChkGroup = document.body.getElementsByClassName("chkGroup");
$.each(allMemberChkGroup, function (i, item) {
item.querySelector("input[type='checkbox']").checked = false;
})
})
});
function ClearAllCheckStatus() {
var allMemberChkGroup = document.body.getElementsByClassName("chkGroup");
$.each(allMemberChkGroup, function (i, item) {
item.querySelector("input[type='checkbox']").checked = false;
})
}
```
### 結果

---
## 開啟新視窗並指定視窗大小和內容 (預覽)
Script
```
function Preview() {
var previewWindow = window.open("", "_blank", "width=800,height=600");
previewWindow.document.write(
"<style> body {padding:50px;} </style>" +
"<title>預覽信件內容</title>" +
CKEDITOR.instances.mailContent.getData()
);
}
```
## 監聽 input 是否已被程式填入資料的方法
一般 User key-in 的資料可以用 onKeyUp 監聽
可是程式寫入的資料完全偵測不到 ! 什麼 onKeyUp、OnInput、OnChange 都是屁
<span style="color:red;font-weight:bold">※目前只監聽過很短的生命週期,如果從頁面載入就開始監聽不知道會不會有效能問題</span>
```
while (true) {
console.log("fail");
if ($("#someInput").val() != "") {
alert("success");
break;
}
}
```