iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Modern Web

舌尖上的JS系列 第 26

D26 - 走!去瀏覽器重現奧運決勝點 in

前言

今天來試著用滑鼠事件重現 2021 奧運羽球決勝點!
麟洋配萬歲~ 台灣萬歲~~

滑鼠 Event 種類

監聽事件提供的事件類別很多,而使用者在瀏覽網頁的時候最常使用的是滑鼠的操作,來看看內建哪些滑鼠事件!

  1. click :滑鼠點擊,定義是使用者在同一個位置完成一次的 mousedownmouseup 動作,觸發順序是 mousedown -> mouseup -> click
  2. mouseup:滑鼠按下後放開時
  3. mousedown:按下滑鼠
  4. mousemove:滑鼠移動,連續移動會連續觸發
  5. mouseover:滑鼠進入節點時,在節點內部移動會觸發多次
  6. mouseenter:滑鼠進入節點時,事件只觸發一次
  7. mouseout:滑鼠離開節點時,會冒泡
  8. mouseleave:滑鼠離開節點時,不會冒泡
  9. contextmenu:按滑鼠右鍵

mouseovermouseout 的目標差異

mouseovermouseout 滑鼠事件中,有兩個目標差異,一個稱為絕對目標 target,一個是相對目標 relatedTarget

mouseover

<div>
  <section class='outerbox mouseover'>
    <p>mouseover</p>
  </section>
</div>
  • event.target:為當下滑鼠觸及到的元素
  • event.relatedTarget :為滑鼠上一個觸及的元素

顯示 targetrelatedTarget 看滑鼠移動時的目標變化

mouseout

<div>
  <section class='outerbox mouseout'>
    <p>mouseout</p>
  </section>
</div>
  • event.target:為當下滑鼠移開的元素
  • event.relatedTarget :為滑鼠進入的元素

顯示 targetrelatedTarget 看滑鼠移動時的目標變化

比較 mouseentermouseovermouseleavemouseout

在滑鼠操作中 mouseenter & mouseover 雖然都是滑鼠移動到節點範圍內產生動作,但是 mouseenter 只會觸發一次,而 mouseover 會因為移動到子節點而持續觸發到目標節點。

mouseleave & mouseout 都是滑鼠離開節點時觸發動作,但 mouseout 事件會 bubbling 到父層,進而讓觸發父層的 mouseout 事件,而 mouseleave 沒有 bubbling,因此父層不會被觸發。

實作不同的滑鼠事件,codepen 連結 -> 滑鼠事件玩玩看

PointerEvent 物件內的屬性

不同的事件類別中,有對應的事件物件可以操作,滑鼠 pointerEvent 包括以下:

可以看到光是有關座標 x、y 軸的就有四種,雖然都是取 x、y 但每個數值計算的座標可不相同

clientXclientY:此座標為滑鼠相對於 瀏覽器可視區域左上角的距離,不會隨著螢幕滾動改變。

pageXpageY:滑鼠相對於瀏覽器可視區域左上角距離,會隨著螢幕滾動而改變

screenXscreenY:滑鼠相對於螢幕可視區域左上角距離,不會隨著螢幕滾動而改變。

offsetXoffsetY:滑鼠相對於物件左上角的距離。

如果光看文字解釋還是不懂,我也做了一個小小的作品來比較滑鼠在不同位置上各類座標的數值差異~~ 多玩幾次相信就可以理解!
座標軸比較

成品

設計想法:重現榮耀羽球場,當界內時顯示 「 in! 」,界外時顯示 「 out 」。

實作:

html 結構

<body>
    <h1>Start</h1>
    <img id="badminton" src="./badminton.png" alt="badminton" />
    <section>
      <div class="base">
        <div class="outerLine"></div>
        <div class="innerLine"><p class="taiwan">aiwan</p></div>
      </div>
    </section>
  </body>

JavaScript 設計想法

// 節點公式放到變數內,之後就不用打落落長取節點囉~
let get = (tag) => document.querySelector(tag);

// 取節點
let inner = get('.innerLine'); // 線內
let h1 = get('h1');      // 顯示結果
let base = get('.base'); // 球場

// 設定球場監聽事件,讓羽球可以隨滑鼠移動
base.addEventListener('mousemove', (event) => {
    // 綁定羽球位置為 clientX, clientY 軸
      let positionX = event.clientX; 
      let positionY = event.clientY;
      badminton.style.top = positionY - 30 + 'px'; // 設定position y軸位置
      badminton.style.left = positionX - 10 + 'px'; // 設定position x軸位置
})
      
// 設定球場監聽事件,當滑鼠移動到界外時 h1 顯示 out
base.addEventListener('mouseenter', (event) => {
      h1.innerHTML = 'out';
});

// 設定界線內監聽事件,界內 h1 顯示 in
inner.addEventListener('mouseenter', (event) => {
      console.log('inner enter');
      h1.innerHTML = 'in!';
});

Reference:

MDN
W3CSchool
JavaScript Info
freePik - 羽球圖片來源

結語

不小心做的好像土銀信用卡 XDD 上上下下修改了好多次,雖然有按照想法實作出來,但總覺得還有更好的寫法,歡迎各位大神指證錯誤或推薦寫法!
/images/emoticon/emoticon41.gif


上一篇
D25 - 走!去瀏覽器吃餅乾 yummy yummy!
下一篇
D27 - 走!去瀏覽器學 Drag & Drop 自己組漢堡包
系列文
舌尖上的JS30

尚未有邦友留言

立即登入留言