0%

JavaScript學徒篇-Event

addEventListener - 事件監聽

addEventListener的括號裡面總共要填入三個引數
第一個: 你想使用的事件,比如: 'click' 點擊事件
第二個: 填入匿名function(),就是你想要做的事情
第三個: 填入false (目前,這堂課還沒講為什麼)

1
2
3
4
5
在Javascript檔案中
var btn = document.querySelector('.btn');
btn.addEventListener( 'click', function(e){
alert('Hello');
}, false);

以上這個範例的addEventListener的作用就是,使用click事件,當觸發click事件的時候,就會跳出Hello的提示訊息。

綁定事件的語法差異-傳統onclick事件 v.s addEventListener

若使用onclick事件

1
2
3
4
5
6
7
8
var btn = document.querySelector('.btn');
btn.onclick = function(){
alert('Hello-1');
}

btn.onclick = function(){
alert('Hello-2');
}

以上,我們將btn元件綁定兩個onclick事件,但最終當我們點擊btn出現的結果會是Hello-2,即第二個函式的結果,這個就是onclick事件的缺點,當你同時對同一個元件綁定多個onclick事件的時候,最終的結果,只會出現最後那一個函式的內容。

addEventListener可同時綁定多個事件

而這也是為什麼有addEventListener的這個功能,因為它可以讓只能綁定一個事件的缺點消失。

像上面這個例子,就可以將btn物件綁定兩個click事件,當我們點擊btn時,會先跳出Hello-1接著才跳租Hello-2。

Event Bubbling、Event Capturing 差異

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---HTML---
<body class="body">
<ul>
<li><a href="#" class="btn">1234</a></li>
<li><a href="#" class="btn">1234</a></li>
</ul>
</body>

---Javascript---
var btn = document.querySelector('.btn');
btn.addEventListener('click',function(e){
alert('btn');
},false);

var body = document.querySelector('.body');
body.addEventListener('click',function(e){
alert('body');
},false);

以上範例,當你點擊btn元件的時候,瀏覽器會先跳出btn,接著,跳出body,會造成這樣的原因,是因為你點擊btn的同時,也會點擊到body的區域。
而在addEventListener的最後一個引數false就跟事件觸發的順序有關,
引數是false : 代表瀏覽器會從指定元素往外找,直到找到document為止,而這也是為什麼上面這個例子會先出現btn後,才接著出現body,因為,他會先去尋找指定元素btn,跳出btn訊息,接著往外找會找到body,跳出body訊息。
引數是true: 代表瀏覽器會從最外層往內找,直到找到指定元素為止,
所以,若改成true的話,以上面這個範例,就會先出現body訊息,接著,才會出現btn訊息。

而以上這兩種狀況分別有各自的術語來代表這些狀況
A. 從指定元素,往外找到document為止 -> Event Capturing(事件擷取)
B. 從外層往內找到指定元素為止 -> Event Bubbling(事件冒泡)

stopPropagation - 中止冒泡事件

如果,我們想要避免當我們按下指定元素之後,
還會再跳出其他外層元素的相關事件內容的話,我們就要在指定元素中,呼叫stopPropagation

1
2
3
4
5
6
7
8
9
10
11
var btn = document.querySelector('.btn');
btn.addEventListener('click',function(e){
e.stopPropagation(); // 記得在function中加入引數e
alert('btn');
},false);

var body = document.querySelector('.body');
body.addEventListener('click',function(e){
e.stopPropagation();
alert('body');
},false);

以上範例,當你點擊btn的時候,
只會出現btn的內容,而沒有再出現body的內容了,
都是因為你再指定元素btn的函式裡面加了e.stopPropagation()的原因,
瀏覽器只會執行那個被監聽元素的內容。

preventDefault - 取消預設觸發行為

通常都用來取消a連結的預設行為
例:
在HTML檔案中

1
2
3
4
5
6
7
8
9
10
11
12
13
<a href="#" class="btn">btn</a>
<a href="www.google.com" class="btn_1">btn_1</a>

在Javscript檔案中
var btn = document.querySelector('.btn');
btn.addEventListener('click',function(e){
e.preventDefault();
},false);

var btn_1 = document.querySelector('.btn_1');
btn_1.addEventListener('click',function(e){
e.preventDefault();
},false);

由以上這個例子,
我們分別在btn和btn_1的監聽事件裡面加入了preventDefault()
所以,當我點擊了btn網頁就不會回到最上方,而是留在原本瀏覽器的位置。
而點擊了btn_1,也不會跳轉到連結的google網頁。

注意!!!!!!!!!!! preventDefault()stopPropagation()的作用,不要搞混囉~~~~

e.target - 了解目前所在元素位置

當你在指定元素的監聽事件裡面,丟e.target就可以得知,當下使用者點擊的是這個指定元素範圍內的哪一個標籤元素
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---HTML---
<div class="header">
<ul>
<li><a href="#"></a></li>
</ul>
</div>

---Javascript---
var el = document.querySelector('header');

el.addEventListener('click',function(e){
console.log(e.target);
concole.log(e.target.nodeName);
},false);

以上面的範例為例,指定元素是header元件,而在header元件區域內有ul, li, a這三種標籤,
當我點擊a的時候,console.log會記錄出<a href="#"></a>,即a標籤
而第二個標籤,會記錄出A,即a連結的節點名稱。
其他的ulli以此類推。

change - 表單內容更動內容時觸發

當我們有一個表單元件,我們在監聽事件裡面會丟入change,表示當該表單元素有更動的時候,執行你想要執行的函式。

1
2
3
4
5
6
7
8
9
10
11
12
13
---HTML---
<select id="areaID">
<option value="前鎮區">前鎮區</option>
<option value="員林市">員林市</option>
</select>

---Javescript---
var el = document.querySelector('#areaID');

function updataList(e){
// do something
}
el.addEventListener('change',updateList,false);

以上的範例,就是當areaID那個表單有更動的時候,就會觸發他的監聽事件,而該監聽事件就會去執行updataList這個函式囉。

而這個功能跟for迴圈結合的範例

以上這個’change’和for迴圈的並用,就是利用list表單有更動的時候,在.name_list裡面顯示出在data陣列裡面area名稱跟option的value的值一樣的name名稱。

keyCode - 點擊鍵盤,射發火箭!

這一個單元教了,keydown這個事件,

以上這個範例,你可以看到我們先擷取到使用者在該網頁的body有按下按鈕,此時,就是keydown事件,接著,透過監聽事件去callback goRocket這個函式,
接著,switch的判斷式,判斷這個event的keyCode是多少,即擷取使用者是按下哪個鈕,若有滿足則跑case裡面的效果。

blur - 離開焦點時進行事件觸發

這個章節,利用input欄位來展示blur的功能,
當使用者將鼠標從input欄位一離開時,就會觸發blur事件,
間接的該input欄位的監聽事件會call back某個函式,
而該函式就可以檢查使用者是否有在該input欄位填入資料,
或者,填入正確型態的資料(像是:應該填入數字 但是 填入字串),進而跳出相對應的提示訊息來提示使用者。

以上範例,就是當使用者離開該input欄位的話,沒有輸入任何東西,會是空字串,則跳出提示訊息囉~~

mousemove - 當滑鼠滑入指定內容時觸發

這章教了,當你對一個物件使用mousemove事件的話,當你的鼠標移入該物件區域時,則會觸發mousemove的事件,並隨即觸發你想要在addEventListener要callback的函式。
而這個事件的應用,可以用在像遊戲的電流急急棒中,當你的鼠標碰到某個區域時,遊戲就會通知你碰到了~~~
例:

1
2
3
4
5
6
7
8
在HTML檔案中
<div class="box"></div>

在Javascript檔案中
var box = document.querySelector('.box');
box.addEventListener('mousemove',function(){
alert('你輸了');
},false);

網頁座標 - 了解 screen、page、client 箇中差異

這個章節利用’mousemove’這個事件,來擷取鼠標的座標,進而介紹
screen, page, client 之間的差別。
screenX, Y: 代表你的鼠標在當前瀏覽器畫面中的鼠標座標(有包含滾動軸和工具列)
pageX, Y: 代表你在網頁內鼠標的實際座標
clientX, Y: 代表鼠標在當網頁內鼠標的座標
你應該會發現我特別,寫瀏覽器畫面和網頁內 這兩個狀態,還有當前的網頁頁面,這些狀態要特別注意

網頁座標 - 應用篇

這一小節,蠻有趣的,學到的擷取鼠標座標應用在這,
將原本的鼠標圖案,換成卡通人物的圖案,並搭配擷取鼠標座標的功能,
來達成在網頁畫面上面卡通人物的圖案會跟著我們鼠標的移動一起移動。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在HTML檔案中
<body>
<div>
<img src="img/pic.png" class="cursor_img" alt="" width="100px;">
</div>
</body>

在css檔案中
.cursor_img{
position: fixed;
}

在Javascript檔案中
var body = document.body;
var img = document.querySelector('.cursor_img');

body.addEventListener('mousemove',function(e){
img.style.left = e.clientX;
img.style.top = e.clientY;
},false);

你可以注意到在CSS檔案中,我們把那個卡通人物的圖案的CSS屬性position設為fixed,
為的是要讓這個卡通人物的圖片能固定在網頁的畫面中,
而沒有特別去設定它的left或top的座標,是因為要用javascript來去動態的設定這個卡通人物的left和top的座標。
另外,注意!!!!!!
你要特別去注意它在Javascript中該卡通人物圖案座標的設定方法,
還要特別寫’px’這樣才能將它的座標位置設進去。

事件監聽優化篇 - 從父元素來監聽子元素內容

這一小節有講到一個特別重要的特性
就是querySelector只會去撈父元素裡面的第一筆資料。
而這個特性會導致,某些子元素不是父元素的第一筆資料,而不會被監聽到。
故我們利用直接監聽該父元素,接著,再用判斷式判斷該事件的nodeName,來看是否是我們想要監聽到的子元素。

以上的例子,可以看到在Javascript中是去監聽父元素.list,而不是直接去監聽子元素.list li。接著,在裡面有個判別nodeName的判斷式,
是為了防止當使用者點到li以外的內容,會記錄我們不想要的內容,故以此來防止。