[小菜一碟] 在 JavaScript 如何讓註冊給事件(Event)的方法只被觸發一次?

這篇文章是一個知識的分享,主要分享給不知道的朋友,我們用 JavaScript 設計一個互動的網頁,一定會用到事件(Event),舉凡像是按鈕的點擊、滑鼠的捲動、選項值的改變、...等等,這些都會需要事件來輔助,但是有時候我們會希望註冊給事件的方法只被觸發一次。

曾經有一個記錄使用者行為的需求,只要使用者捲動網頁,就發送 Request 記錄「某某使用者捲動了網頁」,同一次的瀏覽只記錄一次,所以這個行為記錄的動作只會被觸發一次。

addEventListener/removeEventListener

在 JavaScript 我們可以用 addEventListener 搭配 removeEventListener 來完成這件事情,大略的程式碼及效果如下:

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
    ... 略
  </head>
  <body>
    <img src="https://i.imgur.com/tK6TAsx.jpg" alt="" />
    <script>
        var onScroll = function() {
            console.log("scrolled");

            document.removeEventListener("scroll", onScroll);
        }
        
        document.addEventListener("scroll", onScroll);
    </script>
  </body>
</html>

on/off

如果是習慣用 jQuery 的朋友,jQuery 有 on()off() 搭配使用。

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
    ... 略
  </head>
  <body>
    <img src="https://i.imgur.com/tK6TAsx.jpg" alt="" />
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script>
        var onScroll = function() {
            console.log("scrolled");

            $(document).off("scroll", onScroll);
        }

        $(document).on("scroll", onScroll);
    </script>
  </body>
</html>

once

但是畢竟宣告一個 function,把它註冊進事件,觸發一次再把它從事件中註銷的做法,看上去不是那麼優雅,幸好在約莫 2016 年的時候 addEventListener 的 options 多了一個 once 屬性可以使用,將這個屬性設為 true,就表示事件方法只觸發一次,調整後的程式碼如下:

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
    ... 略
  </head>
  <body>
    <img src="https://i.imgur.com/tK6TAsx.jpg" alt="" />
    <script>
      document.addEventListener(
        "scroll",
        function () {
          console.log("scrolled");
        },
        { once: true }
      );
    </script>
  </body>
</html>

one

jQuery 也有對應的 API - one(),語法更為精簡。

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
    ... 略
  </head>
  <body>
    <img src="https://i.imgur.com/tK6TAsx.jpg" alt="" />
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script>
      $(document).one("scroll", function () {
        console.log("scrolled");
      });
    </script>
  </body>
</html>

以上,如何讓註冊給事件的方法只觸發一次的做法,就分享給還不知道的朋友,希望這個分享有幫助到大家。

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學