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
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
//取得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
13
14
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
10
11
12
13
14
<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
39
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": "登入成功"
}