跳至主要內容

事件委托

Yang大约 2 分钟

描述

如果有许多以类似方式处理的元素,不必为每个元素分配一个处理程序,而是将单个处理程序放在它们的共同祖先上

例子

表格元素添加点击事件

<!-- table 内任意 td 点击高亮,其他 td 取消高亮 -->
<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      td {
        width: 36px;
        height: 36px;
        text-align: center;
        cursor: pointer;
      }

      .highlight {
        background: #f00;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <table border="1">
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>4</td>
        <td>5</td>
        <td>6</td>
      </tr>
      <tr>
        <td>7</td>
        <td>8</td>
        <td>9</td>
      </tr>
    </table>
    <script>
      // 当前高亮元素
      var selectElem = null;

      // 高亮元素
      function highlight(elem) {
        // 判断当前是否有高亮的元素
        if (selectElem) {
          selectElem.classList.remove('highlight')
        }
        selectElem = elem
        elem.classList.add('highlight')
      }
      var table = document.querySelector('table')
      table.onclick = function(event) {
        // 获取点击元素最新的祖先td元素,包括其本身
        const td = event.target.closest('td')
        if (!td) return;
        // 判断td是否在指定table内
        if (!table.contains(td)) return
        highlight(td)
      }
    </script>
  </body>
</html>

按钮添加点击事件

<div id="menu">
  <button data-action="save">Save</button>
  <button data-action="load">Load</button>
  <button data-action="search">Search</button>
</div>

<script>
  class Menu {
    constructor(elem) {
      this._elem = elem
      elem.onclick = this.onClick.bind(this)
      // elem.onclick = (event) => {
      //   this.onClick(event)
      // }
    }
    save() {
      console.log('saving')
    }
    load() {
      console.log('loading')
    }
    search() {
      console.log('searching')
    }
    onClick(event) {
      const button = event.target.closest('button')
      if (!button) return
      const action = button.dataset.action
      this[action]()
    }
  }
  new Menu(document.getElementById('menu'))
</script>

计数器

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      input {
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <input type="button" value="1" data-count>
    <input type="button" value="1" data-count>
    <input type="button" value="1" data-count>
    <input type="button" value="1" data-count>
    <input type="button" value="1" data-count>
    <input type="button" value="1" data-count>

    <script>
      document.addEventListener('click', function(event) {
        if (event.target.dataset.count != undefined) {
          event.target.value++
        }
      })
    </script>
  </body>
</html>

切换器

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    <button data-toggle-id="form">
      显示/隐藏 FORM
    </button>
    <br><br>
    <form id="form" hidden>
      邮箱: <input type="email">
    </form>
    <script>
      document.addEventListener('click', function(event) {
        const toggleId = event.target.dataset.toggleId
        if (!toggleId) return
        const elem = document.getElementById(toggleId)
        elem.hidden = !elem.hidden
      })
    </script>
  </body>
</html>
上次编辑于:
贡献者: sunzhenyang