JS-基礎用法


Selector - 選擇元素

  • element = document.querySelector(selectors);
    • element 是元素物件。
    • selectors 是以逗號分隔,包含一個或多個 CSS 選擇器的字串。
選擇單一元素 querySelector
1
2
//回傳第一個符合條件的元素
var el = document.querySelector("#titleId");
選擇多個元素 querySelectorAll
1
2
//回傳符合條件的元素
var el = document.querySelectorAll(".titleClass");

Attribute - 增加標籤屬性

  • setAttribute 設定
設定 標籤屬性
1
2
var el = document.querySelector(".titleClass a");
el.setAttribute("href", "http://www.yahoo.com.tw");
  • getAttribute 取得
取得 標籤屬性
1
2
var el3 = document.querySelector(".titleClass a").getAttribute("href");
console.log(el3);

innerHTML - 插入 HTML

將元素內的 html重新覆蓋寫入新的 html。

插入HTML
1
2
3
var el = document.getElementById("main");
var str = '<h1 class="blue">1234</h1>';
el.innerHTML = str;

createElement - 插入 dom 元素

建立一個新的 DOM 元素,然後再使用 appendChild 新增子節點,並不會覆蓋原有的 DOM 元素。

新增dom元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h1 class="title">
<em>titile</em>
</h1>

<script>
// 建立元素
var sonElement = document.createElement("a");
sonElement.setAttribute("href", "www.facebook.com");
sonElement.textContent = "前往Facebook";

// 增加子節點
var fatherElement = document.querySelector(".title");
fatherElement.appendChild(sonElement);
</script>
更新後結果
1
2
3
4
<h1 class="title">
<em>titile</em>
+ <a href="www.facebook.com">前往Facebook</a>
</h1>
使用 appendChild 要注意的小細節:
要留意的是 如果 appendChild 使用時,append 上去的是一個已存在的 node 時,它會做的是搬移,而非複製
所以 appendChild 使用時要複製而非搬移,記得先使用 Node.cloneNode() 這個方法複製 Node Element。

參考:PJ - Node Element 在 appendChild 後消失(disappear)!?


addEventListener - 事件氣泡、事件捕捉

基本語法

element.addEventListener(event, function, useCapture)

  • 第三個參數:可省略,預設為 false

範例

可試試將第三個參數分別改成 truefalse,各執行一次,會有什麼不一樣的結果。

html
1
2
3
<div class="warp">
<div class="box"></div>
</div>
預設:事件氣泡-從指定元素往外找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var el = document.querySelector(".box");
el.addEventListener(
"click",
function() {
alert("box");
console.log("box");
},
false
);

var elBody = document.querySelector(".body");
elBody.addEventListener(
"click",
function() {
alert("body");
console.log("body");
},
false
);
// false (事件氣泡 - event Bubbling) - 從指定元素往外找
// true (事件捕捉 - event capturing) - 從最外面找到指定元素

See the Pen addEventListener - 事件氣泡、事件捕捉 by Kanboo (@Kanboo) on CodePen.

stopPropagation - 中止冒泡行為

依上例 addEventListener-事件氣泡 因素,有時只是想單純針對單一元素監聽,不想因為事件冒泡的行為,而去觸發到其他元素,這時就可利用 stopPropagation 來達成此需求。

1
2
3
4
5
6
var el = document.querySelector('.box');
el.addEventListener('click',function(e){
+ e.stopPropagation(); // 中止冒泡行為
alert('box');
console.log('box');
},false);

事件監聽優化 & e.target

有時子元素可能要上千個,每個都要綁上監聽的話,效能不是很優,這時可從父節點下手,使用 e.target.nodeName 判斷是否為 想監聽的子元素,若是為想監聽的子元素,可再用 e.target.value 或是 e.target.textContent 取得 值。

  • e.target.nodeName 取得點擊元素的標籤名稱,如:UL、LI、INPUT…
  • e.target.value 取得選取元素的值

範例

當有一個 ul 底下有多個 li 都要監聽的話,這時我們可以利用 addEventListener-事件氣泡 的原理,只要針對 ul 監聽,讓他往上冒泡,當到達 li 時,這時我們就可以針對 li 做事了。

原始寫法
1
2
3
4
5
6
7
8
9
10
11
//取得ul底下的所有li元素
var list = document.querySelectorAll(".list li");
//forloop,將每個li元素綁上監聽事件(N次)
var len = list.length;
for (var i = 0; len > i; i++) {
list[i].addEventListener("click", checkName, false);
}

function checkName(e) {
console.log(e.target.textContent);
}
優化寫法
1
2
3
4
5
6
7
8
9
10
11
//取得ul元素
var list = document.querySelector(".list");
//將ul元素綁上監事件(一次)
list.addEventListener("click", checkName, false);

function checkName(e) {
if (e.target.nodeName !== "LI") {
return;
} // 判斷是否為li元素
console.log(e.target.textContent);
}

preventDefault - 取消預設觸發行為

比較常用在 a 連結的 hrefForm 表單的 submit 上,有時可能只是想觸發呼叫 Function,而不想使用到原生附與的功能的話,就可利用 preventDefault 達成此需求。

取消預設觸發行為
1
2
3
4
5
6
var list = document.querySelector("a");
list.addEventListener("click", function(e) {
e.preventDefault(); //取消預設觸發行為

/* 撰寫你的Code */
});

localStorage - 灠瀏器資料儲存

基本語法

儲存
1
localStorage.setItem("countryItem", countryString);
讀取
1
localStorage.getItem("countryItem");

範例

localstorage 只能保存 string 資料,所以當資料非字串型態的話,記得轉為字串string

JSON.stringify() 將 array 轉為 string
JSON.parse() 將 string 轉為 array
1
2
3
4
5
6
7
8
9
10
11
12
var country = [{ farmer: "王農夫" }];

//儲存
var countryString = JSON.stringify(country); // 轉字串
console.log(countryString);
localStorage.setItem("countryItem", countryString);

//讀取
var getData = localStorage.getItem("countryItem");
var getDataAry = JSON.parse(getData); // 轉array

console.log(getDataAry[0].farmer);
補充小知識
var data = listData;
var data2 = listData || []; //(建議寫法)

console.log(‘沒有 []’, data); // 有可能取得資料或 undefined
console.log(‘加上 []’, data2); // 有可能

data-* - 透過 dataset 讀取自訂資料

  • 名字絕對不能以 xml 起頭,無論是否用於 xml、
  • 名字絕對不能包含分號(U+003A)、
  • 名字絕對不能包含大寫 A 到大小 Z 的拉丁字母。

可透過 HTMLElement.dataset.testValue 或 HTMLElement.dataset[“testValue”] 訪問

1
2
3
4
5
6
7
8
9
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>
John Doe
</div>

let el = document.querySelector('#user'); // el.id == 'user' // el.dataset.id
=== '1234567890' // el.dataset.user === 'johndoe' // el.dataset.dateOfBirth ===
'' el.dataset.dateOfBirth = '1960-10-03'; // set the DOB. // 'someDataAttr' in
el.dataset === false el.dataset.someDataAttr = 'mydata'; // 'someDataAttr' in
el.dataset === true

AjAX

屬性

readyState:
 0:尚未讀取
 1:讀取中
 2:已下載完畢
 3:資訊交換中
 4:處理完畢

Status:即HTTP 協定的狀態碼

當 readyState == 4,代表有執行完成,但不一定是有正確撈到資料,
要配合 HTTP status == 200,才代表是正確撈到資料。

範例

利用 AJAX 傳送(POST)帳號、密碼資料至後端註冊會員帳號。

POST資料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var send = document.querySelector(".send");
send.addEventListener("click", signup, false);

function signup() {
var emailStr = document.querySelector(".account").value;
var passwordStr = document.querySelector(".password").value;

//資料丟到物件
var account = {};
account.email = emailStr;
account.password = passwordStr;

var xhr = new XMLHttpRequest();
xhr.open("post", "https://hexschool-tutorial.herokuapp.com/api/signup", true);
xhr.setRequestHeader("Content-type", "application/json"); //宣告json格式
var data = JSON.stringify(account); //轉成字串
xhr.send(data); // 送出

//ajax完成後,執行此event
xhr.onload = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// 萬事具備
var callbackData = JSON.parse(xhr.responseText); //接收回傳後資料
console.log(callbackData);
var veriStr = callbackData.message;
if (veriStr == "帳號註冊成功") {
alert("帳號註冊成功!!");
} else {
alert("帳號註冊失敗!");
}
} else {
// 似乎有點問題。
// 或許伺服器傳回了 404(查無此頁)
// 或者 500(內部錯誤)什麼的。
alert("伺服器處理錯誤");
}
};
}
ajax回傳的格式
1
2
3
4
5
{
"success": true,
"result": {'結果'},
"message": "登入成功"
}