将点击事件处理程序绑定到大量元素的机制

时间:2018-10-14 12:20:36

标签: javascript

我正在编写一个大的HTML表,该表具有相同的数据着色功能,这是通过用户双击某个单元格来实现的,该表有8000多个单元格,并且单元格将增加。 在这一点上,我认为网络浏览器的工作负担可能很大。 是的,我想知道将事件处理程序附加到大量<td>元素上的深入机制和负担程度。

代码:

<script>
   var otable = document.getElementById("htbl_drawresult");
   var irIndex = 0;
   var icIndex = 0;
   var sintxt = "";

    for(var i = 1; i < otable.rows.length; i++)
    {
        for(var j = 0; j < otable.rows[i].cells.length; j++)
        {
            otable.rows[i].cells[j].ondblclick = function()
            {
                irIndex = this.parentElement.rowIndex;
                icIndex = this.cellIndex+1;
                sintxt = this.innerText;                    
                f_colorcell(sintxt, otable);
            };
        }
    }

    function f_colorcell(stxt, otbl){
        var irow = otbl.rows.length;
        var icol = otbl.rows[1].cells.length;
        var i,j=0;

        for(i=1; i<irow; i++)
        {
            for(j=0; j<icol; j++)
            {
               if (otbl.rows[i].cells[j].innerText == stxt){
                   otbl.rows[i].cells[j].style.background=\"red\";
               }
            }
        }
    }        
</script>

3 个答案:

答案 0 :(得分:0)

如果您要为表中的单元格(<td>)分配事件处理程序,则可以通过两种方式做到这一点:

1。事件传播

  • 一种更短,更简单的方法。您可以将事件处理程序分配给父级(<table>元素本身),其中的所有内容也将具有事件处理程序。简而言之,父母得到的,孩子也会得到的。

    • 如果您不需要在单击给定元素时发生特定的事情,则建议使用。虽然,您始终可以利用Event.Target缩小范围。
    • 在下面的示例中,我为表(父级)分配了一个click事件监听器,这样,当您单击表中的任何内容时,都会出现一条警告,提示您“单击了一个单元格,其值为[单元格值]”将会显示
    • 这里是working example,用于事件传播。

    • window.onload = ()=>{
        // get our table
        let tb = document.getElementById('main-table');
        // assign a click event to it
        tb.addEventListener('click', (e)=>{
          alert(`You clciked on a cell and it had the value of ${e.target.innerHTML}`)
        })
      }
      <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
      
      <table class="table" id="main-table">
        <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
        </tbody>
      </table>

2。手动为每个元素分配一个特定的事件处理程序

  • 您始终可以为每个单元格(<td>设置事件处理程序,特别是通过使用JavaScript的内置函数(即querySelectorquerySelectorAll,{{3 }}等),然后使用getElementById

    分配要在特定事件上调用的函数
    • 不推荐,用于大量元素。
    • 您可以使用addEventListener下面的代码段:)

    • window.onload = ()=>{
        // get our table
        let table = document.getElementById('main-table');
        // get all the cells in the table element above
        let tableCells = table.querySelectorAll('td');
        // assign an event listener to each cell <td> element inside that table specifically
        for(let i = 0; i < tableCells.length; i++){
          tableCells[i].addEventListener('click', function(e){
            alert(`You clicked on cell index ${i} and it had the value of ${this.innerHTML}`);
          })
        } 
      }
      <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
      
      <table class="table" id="main-table">
        <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
        </tbody>
      </table>

:)

答案 1 :(得分:0)

只需总结@ C.RaysOfTheSun的答案:

是的,在表的每个单元格上附加一个事件会很麻烦。

但是,您可以通过这样的方式来构造HTML,使得每个单元格(TD s都可以唯一地标识。而且,当事件从目标传播到连接了 * commonly * 的监听器的祖先(例如TABLE元素)时,很容易确定监听器中的实际目标。

document.addEventListener("DOMContentLoaded", main, false);

function main() {
  var table = document.getElementsByTagName("TABLE")[0];

  table.addEventListener("dblclick", handleDoubleClickOnTable, false);
}

function handleDoubleClickOnTable( /* event => */ e) {

  var target = e.target;
  var row, column;
  var rowNumber, columnNumber;

  if ("TD" !== target.tagName) {
    return;
  }

  row = target.parentNode;
  column = target;

  rowNumber = row.dataset.rowNumber;
  columnNumber = column.dataset.columnNumber;

  alert(`You clicked on ( row[ ${ rowNumber } ], column[ ${ columnNumber } ] )`);
}
* {
  font-family: monospace;
  box-sizing: border-box;
}

table {
  width: 100%;
  margin-bottom: 1rem;
  background-color: transparent;
  border-collapse: collapse;
}

td {
  vertical-align: bottom;
  border-bottom: 2px solid #dee2e6;
  border-top: 1px solid #dee2e6;
  padding: 2rem;
}
<!-- Sample 3 x 3 table -->
<table>
  <tr data-row-number="1">
    <td data-column-number="1">( 1, 1 )</td>
    <td data-column-number="2">( 1, 2 )</td>
    <td data-column-number="3">( 1, 3 )</td>
  </tr>
  <tr data-row-number="2">
    <td data-column-number="1">( 2, 1 )</td>
    <td data-column-number="2">( 2, 2 )</td>
    <td data-column-number="3">( 2, 3 )</td>
  </tr>
  <tr data-row-number="3">
    <td data-column-number="1">( 3, 1 )</td>
    <td data-column-number="2">( 3, 2 )</td>
    <td data-column-number="3">( 3, 3 )</td>
  </tr>
</table>

答案 2 :(得分:-1)

如果要添加单击事件侦听器,则可以使用jQuery。您可以将其用于任何HTML元素。

$("#button").click(function() {
  $("#result").css("background-color", "yellow");
});
$("#button").dblclick(function() {
  $("#result").css("background-color", "red");
});
body {
  font-family: Arial, sans-serif;
}
td {
  width: 20px;
  height: 20px;
  text-align: center;
  margin: 0;
  border: .5px solid black;
}
#button {
  background-color: white;
}
#result {
  background-color: blue;
  width: 100px;
  height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

If you click the <code>div</code> once, the square will turn yellow.<br>
If you double click the <code>div</code>, the square will turn red.<br>
CM = Click Me
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
  </tr>
  <tr>
    <td>6</td>
    <td>7</td>
    <td id="button">CM</td>
    <td>9</td>
    <td>10</td>
  </tr>
  <tr>
    <td>11</td>
    <td>12</td>
    <td>13</td>
    <td>14</td>
    <td>15</td>
  </tr>
  <tr>
    <td>16</td>
    <td>17</td>
    <td>18</td>
    <td>19</td>
    <td>20</td>
  </tr>
</table>
<div id="result"></div>