首页 > 解决方案 > 如何在 html 表格中启用可点击的新添加行?

问题描述

我有一个表格,每一行都有一个类“.clickablerow”,当点击这一行时,我定义了 onclick 函数,会出现一个对话框,然后我可以在上面或下面插入一些文本作为新行。问题是,虽然我已经在这些新添加的行中添加了“.clickablerow”,但它们实际上是不可点击的,也没有出现这样的对话框。

我的代码是这样的:

JS:

$(document).ready(function() {
        $(".clickable-row").click(function(){

           var i = $(this).rowIndex;
           var html = "<tr class='clickable-row' > <td> a test </td></tr>";

           $('#table_id > tbody > tr').eq(i).after(html);
});

HTML:

<head>
...
    <link rel="stylesheet" href="../static/css/main.css">
    <link rel="stylesheet" href="./static/css/bootstrap.min.css">
    <script src="./static/js/jquery.min.js"></script>
    <script src="./static/js/bootstrap.min.js"></script>
    <script src="./static/js/jquery.expander.min.js" type="text/javascript"></script>
    <script src="./static/js/main.js" type="text/javascript"></script>
....
<head>

<body>
....
  <table>
      <tbody>
         <tr class='clickable-row' >
          <td style="border: 0;"> Initial message ....</td>
         </tr>
      </tbody>
</table>
....
</body>

如果我单击该行,将添加一个具有“可点击行”类的新行,但是,该新行不可点击。欢迎任何想法!谢谢

标签: javascriptjqueryhtml

解决方案


只需将事件委托click<table><tbody>

const tableBody = document.getElementById('tableBody');

tableBody.onclick = (e) => {
  const target = e.target;
  
  let row = target;
  
  while (!row.classList.contains('clickable-row') && row !== tableBody) row = row.parentElement;
  
  if (row === tableBody) {
     return; // Ignore the click if we could not find a .clickable-row
  }

  const newRow = tableBody.insertRow(target.rowIndex);

  newRow.className = Math.random() < 0.5 ? 'clickable-row' : 'disabled-row';
  newRow.innerHTML = '<td>...</td>';
};
table {
  font-family: monospace;
  width: 100%;
  border-collapse: collapse;
  text-align: center;
  user-select: none;
}

tr.disabled-row {
  background: #EEE;;
}

tr.clickable-row {
  cursor: pointer;
}

tr.clickable-row:hover {
  background: yellow;
}

td {
  border: 2px solid black;
  padding: 8px 4px;
}
<table>
  <tbody id="tableBody">
    <tr class="clickable-row"><td>...</td></tr>
  </tbody>
</table>

使用 jQuery,您可以使用.on()

委托事件的优点是它们可以处理来自以后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委托事件来避免频繁附加和删除事件处理程序的需要。例如,该元素可以是模型-视图-控制器设计中视图的容器元素,或者如果事件处理程序想要监视文档中的所有冒泡事件,则可以是文档。在加载任何其他 HTML 之前,文档元素在文档的头部是可用的,因此在此处附加事件是安全的,而无需等待文档准备好。

除了能够处理尚未创建的后代元素上的事件之外,委托事件的另一个优点是当必须监视许多元素时,它们的开销可能会大大降低。在其 tbody 中有 1,000 行的数据表上,此示例将处理程序附加到 1,000 个元素:

$( "#dataTable tbody tr" ).on( "click", function() {
    console.log( $( this ).text() );
});

事件委托方法仅将事件处理程序附加到一个元素,即 tbody,并且事件只需要冒泡一个级别(从单击的 tr 到 tbody):

$( "#dataTable tbody" ).on( "click", "tr", function() {
    console.log( $( this ).text() );
});

前面的示例将如下所示:

$('#tableBody').on('click', '.clickable-row', (e) => {
  $(e.currentTarget).after(`<tr class=${ Math.random() < 0.5 ? 'clickable-row' : 'disabled-row' }><td>...</td></tr>`);
});
table {
  font-family: monospace;
  width: 100%;
  border-collapse: collapse;
  text-align: center;
  user-select: none;
}

tr.disabled-row {
  background: #EEE;;
}

tr.clickable-row {
  cursor: pointer;
}

tr.clickable-row:hover {
  background: yellow;
}

td {
  border: 2px solid black;
  padding: 8px 4px;
}
<table>
  <tbody id="tableBody">
    <tr class="clickable-row"><td>...</td></tr>
  </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


推荐阅读