JavaScript 小學 — event 事件(ep2)

Jordan Tseng
JordanTTCDesign
Published in
11 min readDec 20, 2020

接續上篇,接著分享幾個 event object 中常見屬性和更多 event 觸發事件:

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

因為網頁上經常是包著很多層的元素🤟,又加上冒泡事件,有時候是需要知道到底我們觸發哪一個 DOM 元素,就可以 e.target 來得知🤓。

假設 HTML 有 <ul><li> 👻👻

<ul><li class="test">hi</li></ul>

我透過 e.target ,就會得到完整的 "<li class='test'>hi</li>" 🙆‍♂️。

var el=document.querySelector('.test');
el.addEventListener('click',function(e){
console.log(e.target);
},false);

小補充,thise.target 有點像,但是他們之間的區別是: 隨著 js 冒泡事件的發生,this 是會變化的,但 e.target 不會變化,它永遠是指觸發事件的 DOM 物件😋。

延伸 e.target .nodeName

剛剛說到 e.target ,會帶出觸發的完整 html 結構,而 .nodeName是只有帶出觸發的 html 標籤:

var el=document.querySelector('.test');
el.addEventListener('click',function(e){
console.log(e.target);
//會得到"<li class='test'>hi</li>"
console.log(e.target.nodeName);
//會得到LI
},false);

這能幹啥呢?💁💁💁

→利用父層監聽子元素

像 ul&li 的例子,因為像上面監聽都是先 querySelector 一個元素才去做綁定對吧?又或是 querySelectorAll 出一組陣列,再透過迴圈全部綁定一次,但是這樣其實是很消耗效能😱😱。所以才會想到說監聽父層來監聽子元素,再透過判斷式來做判斷他的 .nodeName 是 LI:

var el = document.querySelector('ul');
el.addEventListener('click',function(e){
//nodename可以確定說點到是哪個標籤,可用於if判斷
if(e.target.nodeName !== 'LI'){return};
alert('你點到li');
},false)

這裡的 return 是說,點到不是 LI 不想執行任何程式,就用 return 跳出 function。可以利用下面的 codePen 點點看。

e.value 搭配 change 事件

e.value 是元素的值,而當inputselecttextarea 元素的值被改變後,會觸發 change事件。

但要注意一件事就是,只有用 select 的是選擇後馬上觸發,而其他的是要用戶焦點離開之後才會觸發唷~

所以用一個舉例來看,假設看看住在台北市和新北市的朋友有誰?🧐

<select id="areaId">
<option value="台北市">台北市</option>
<option value="新北市">新北市</option>
</select>
<ul class="list"></ul>

當改變 select 時會觸發 change 然後執行 function updateList(),就會把結果顯示在 list 中!!❤️

let area = document.querySelector('#areaId');
let list = document.querySelector('.list');
let friends = [
{
name: 'Jordan',
place: '台北市'
},
{
name: 'Lawrence',
place: '台北市'
}
,{
name: 'Zoe',
place: '新北市'
}
]
function updateList(e){
let select = e.target.value;
let str='';
for(var i=0;i<friends.length;i++){
if(select== friends[i].place){
str += '<li>'+friends[i].name+'住在'+friends[i].place+'</li>'
}
}
list.innerHTML = str;
}
area.addEventListener('change',updateList,false)

剛剛說到除了 select 是一選擇結果就會觸發 change ,而像 inputvalue 被改變,需要等到離開焦點才會觸發,那其實也能用焦點事件,來觸發程式唷~ blur 的效果就是當滑鼠"取消焦點"時 → 就會觸發" blur 事件"😺。

最常見的範例就是✌️,當離開 input 時檢查填空區是否填寫了內容:

function check(e){
let str = e.target.value
if(str ==''){alert('此處不能為空')}
}
input.addEventListener('blur',check,false);

既然有離開就有進入, focus 的效果是當滑鼠"點擊到欄位內"時 → 會觸發 "focus事件",下面是一個比較完整的範例:

按鈕隱藏的秘密:keydown & e.keyCode

鍵盤上每一個按鈕按下後其實都有一個代號,我們可以利用 keydown 監聽,再用 e.keyCode 就可以找到它並觸發事件,最常見的就是 Enter 拉~當輸入完按下 enter 就可以直接下一步或是查詢等等,這比用滑鼠去按按鈕快多了!我們就試著來找出 enter 的代號吧!

const body = document.body;
function checkKeyCode(e) {
console.log(e.keyCode);
}
body.addEventListener("keydown",checkKeyCode, false);

他的步驟解析是:

  1. 先選取到 body 這個 DOM 元素。
  2. 建立一個函式,並來確認一下按鍵的編號。
  3. 最後跟上面說到的從父層監聽子元素一樣,那就直接監聽 body 內所有按鈕互動。

答案是 13 唷👈👈~~

其實在遊戲中也大多都是如此的喔~來用 keyCode 控制畫面中的方塊~這時候可以用 switch 來做判斷,因為 keyCode 直接就是一個數值,用 case 直接做比對比 if else 判斷更減少效能消耗🤘🤘。

const body = document.body;
function gogoBox(e){
//先找到keycode代碼
console.log(e.keyCode);
switch(e.keyCode){
//按下1
case 49:
document.querySelector('.box-1').style.bottom='300px';
break;
//按下2
case 50:
document.querySelector('.box-2').style.bottom='100px';
break;
//按下3
case 51:
document.querySelector('.box-3').style.bottom='200px';
break;
};}
body.addEventListener('keydown',gogoBox,false);

附上網路上的鍵盤代碼表:https://www.itread01.com/content/1547188864.html

滑鼠移動進特定區域時:mousemove

滑鼠事件,顧名思義就是利用滑鼠鼠標來觸發 funtion,當然他也是必須要先綁定一個指定區域,在指定區域有滑鼠移動時觸發,他是有很多不同的觸發情況👀👀👀:

我們用實際案例來試試看吧😋

<div class="txtBox">
<p class="txt">Hello</p>
</div>

上面是一個div>p,我們綁定 .txt ,當滑鼠滑過去就會加入文字。

const txt =document.querySelector('.txt');
var str =txt.textContent;
function addNote(e){
str=str+'World';
txt.textContent =str;
e.stopPropagation();
}
// 只要存在於區域內會持續觸發
// txt.addEventListener('mousemove',addNote,);
// 只有在進去時才會觸發
txt.addEventListener('mouseenter',addNote,);
// 只有在離開時才會觸發
// txt.addEventListener('mouseleave',addNote,);

看到這篇文章,還有更多滑鼠事件的範例唷:Mouse Event 小筆記

螢幕監聽事件

螢幕監聽超實用!!👷‍♂️可以把 logo 當作滑鼠鼠標、畫面滾動特定高度就會改變某些區塊元素…等等的。要如何做呢?要先監聽整個 body,在 body 綁定 mousemove 事件,最後搭配 function(e){裡面的 e.screene.pagee.client}!!這三個有什麼差別,來看看吧:

  • screen:是監聽整個電腦螢幕的 X 軸、Y 軸座標
  • page:是監聽整個網頁的 X 軸、Y 軸座標,所以網頁可能非常長
  • client:是監聽個網頁視窗的 X 軸、Y 軸座標

下面是六角學院課程中老師示範的程式碼,只要偵測鼠標的 X 軸、Y 軸座標即可以改變圖片的絕對定位 left 和 top,就可以讓圖片跟著鼠標。

var clientX = document.querySelector('.clientX');        
var clientY = document.querySelector('.clientY');
var mouseImg = document.querySelector('.mouseImg');
function getPosition(e) {
clientX.textContent = e.clientX;
clientY.textContent = e.clientY;
//修改DOM的css樣式,偵測游標目前位置並作為position:fixed;的top跟left數值
mouseImg.style.left =e.clientX+'px';
mouseImg.style.top =e.clientY+'px';
}
var el = document.body;
el.addEventListener('mousemove', getPosition, false);

--

--