繁体   English   中英

仅使用 javascript 使表格行可单击但标题不可单击

[英]Make table row clickable but not headers only with javascript

有没有办法只使用 javascript 而没有 jquery来存档与这篇文章中描述的相同的内容? 目标是检测单个行上的点击,同时忽略 header 上的点击。

到目前为止我的方法:

 document.addEventListener('click', function(e) { var table = document.getElementById("table01"); var rows = table.getElementsByTagName("tr"); for (i = 0; i < rows.length; i++) { rows[i].addEventListener('click', function(e) { console.log('clicked') }) } })
 <table class="table table-striped" id="table01"> <thead class="thead-green"> <tr> <th scope="col">A</th> <th scope="col">B</th> </tr> </thead> <tbody> <tr> <td>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <td>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <td>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> </tbody> </table>

我会避免将事件侦听器附加到每个单独的行,原因有两个:

  1. 如果表太长,大量的事件监听器会损害性能
  2. 如果表格内容是动态的,则新添加的行将需要添加新的侦听器。

相反,您可以在整个表上附加一个事件侦听器,并检查点击目标是否在tbody内。 (这也被称为 JavaScript 中的事件委托模式)

 var table = document.getElementById("table01"); table.addEventListener('click', e => { if (e.target.closest('tbody')) { console.log(e.target.closest('tr')); // emit the row you just clicked; } });
 <table class="table table-striped" id="table01"> <thead class="thead-green"> <tr> <th scope="col">A</th> <th scope="col">B</th> </tr> </thead> <tbody> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> </tbody> </table>

甚至比这更简单,您可以将事件侦听器附加到tbody上。 这样您就可以保证所有点击都来自表体中的行。

 var tableBody = document.getElementById("table01").querySelector('tbody'); tableBody.addEventListener('click', e => { if (e.target.closest('tr')) { console.log(e.target.closest('tr')); // emit the row you just clicked; } });
 <table class="table table-striped" id="table01"> <thead class="thead-green"> <tr> <th scope="col">A</th> <th scope="col">B</th> </tr> </thead> <tbody> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> <tr> <th>Item 1</td> <td>Item 2</td> <td>Item 3</td> </tr> </tbody> </table>

同时,请考虑您所需行为的可访问性。 键盘用户将如何触发这种点击? 屏幕阅读器用户如何知道这些行实际上是“可点击的”?

只是对你的javascript做了一点修改。 请参阅提供的代码:

document.addEventListener('click', function(e) {
  var table = document.getElementById("table01");
  var rows = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    rows[i].addEventListener('click', function(e) {
      alert('clicked');
    })
  }
});

你会看到修改是在 Your var rows = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr"); . 通过这种方式,您将仅使用纯javascripttbody获取行,而不是整个表( theadtfoot ),并且也避免使用querySelector

document.querySelectorAll("#table01>tbody>tr").forEach(function(tr){tr.addEventListener....};

">" 代表直接子代。

收集一个变量中的所有标题并检查其中是否有任何一个是每一行的后代

var headers = document.getElementsByTagName("th");
for (i = 0; i < rows.length; i++) {
       var hasHeader = false;
        for (j = 0; j < headers.length; j++) {
                 if(rows[i].contains(headers[j])) {
                        hasHeader = true;
                        break;
                } 
      } 
        if(!hasHeaders) {
             rows[i].addEventListener('click', function(e) {
              console.log('clicked')
            })
      } 
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM