關於preventDefault和stopPropagation

簡單記錄了關於preventDefault和stopPropagation使用


在網頁開發中,事件處理是網頁重要的一部分。網頁經常會提供各種事件來和網頁的元素互動,像是用戶點擊按鈕、提交表單。

而事件由於瀏覽器的事件冒泡和委託,導致一些事件會被其他元素的事件觸發,而使事件行為變得不可控和預測。要解決這部分的兩個常用的方法——preventDefaultstopPropagation能良好的解決該問題。

這篇文章會介紹這兩個方法的用途及其區別。

preventDefault

作用

preventDefault 用於阻止事件的默認行為。每當事件被觸發時,瀏覽器會根據該事件執行一些預設動作。比如,點擊一個鏈接會跳轉到指定的 URL,提交表單會刷新頁面並將數據提交到服務器。使用 preventDefault 可以阻止這些默認行為的發生。

使用情境

  1. 表單驗證:在提交表單之前,我們通常需要驗證用戶輸入的數據是否符合要求。使用 preventDefault 可以阻止表單的默認提交行為,從而在前端完成驗證。
<body>
  <form id="myForm">
    <label for="name">姓名:</label>
    <input type="text" id="name" name="name" required />
    <button type="submit">提交</button>
  </form>
 
  <script>
    document.querySelector('form').addEventListener('submit', function (event) {
      event.preventDefault();
      // 驗證邏輯
      const name = document.getElementById('name').value;
      if (name.length > 2) {
        console.log('驗證通過');
      } else {
        console.log('姓名長度要大於2。');
      }
    });
  </script>
</body>
  1. 自定義鏈接行為:有時我們希望點擊鏈接後執行一些自定義邏輯,而不是跳轉到其他頁面。
<body>
  <a href="https://example.com" id="myLink">點擊我</a>
 
  <script>
    document.querySelector('a').addEventListener('click', function (event) {
      event.preventDefault();
      // 自定義邏輯
      console.log('鏈接點擊被攔截,自定義邏輯執行。');
    });
  </script>
</body>

MDN - Event cancelable 並且我們可以使用 event.cancelable 來確定事件是否可以被取消(cancelable),我們用下面使用滾輪事件的例子來說明:

<body>
  <div style="height: 2000px;">
    <p>滾動鼠標滾輪來觸發事件</p>
  </div>
 
  <script>
    function preventScrollWheel(event) {
      if (typeof event.cancelable !== 'boolean' || event.cancelable) {
        // 事件可被取消,因此我們取消它。
        event.preventDefault();
        console.log('滾輪事件可以被取消,已調用 preventDefault。');
      } else {
        // 事件不可被取消,因此我們不應該調用 preventDefault。
        console.warn('滾輪事件不能被取消:');
        console.dir(event);
      }
    }
 
    document.addEventListener('wheel', preventScrollWheel);
  </script>
</body>

stopPropagation

作用

stopPropagation 方法用於阻止事件冒泡。當一個事件在某個元素上觸發時,該事件會沿著 DOM 樹向上冒泡,逐層觸發其祖先元素的同類事件。使用 stopPropagation 可以防止事件冒泡到父級元素。

使用情境

  1. 防止重複觸發事件:在某些情況下,子元素和父元素都綁定了相同類型的事件處理器,而我們只希望子元素的事件處理器執行。
document.querySelector('.child').addEventListener('click', function (event) {
  event.stopPropagation();
  // 子元素的點擊處理邏輯
});
 
document.querySelector('.parent').addEventListener('click', function (event) {
  // 父元素的點擊處理邏輯
});
  1. 模態窗口或彈出框:在實現模態窗口或彈出框時,點擊窗口外部區域通常會關閉窗口。此時,可以使用 stopPropagation 防止點擊事件冒泡到外部區域。
document.querySelector('.modal').addEventListener('click', function (event) {
  event.stopPropagation();
  // 模態窗口的點擊處理邏輯
});
 
document.querySelector('.overlay').addEventListener('click', function () {
  // 關閉模態窗口
});

preventDefaultstopPropagation 的區別

雖然 preventDefaultstopPropagation 都是用於控制事件行為的方法,但它們的作用和使用場景是不同的。

  • preventDefault:阻止事件的默認行為(如表單提交、鏈接跳轉等)。適用於我們希望覆蓋或修改瀏覽器默認行為的情況。
  • stopPropagation:阻止事件冒泡,防止事件向上傳播。適用於我們希望控制事件流向,避免在父級元素上觸發相同事件處理器的情況。