#javascript #html #typescript
#javascript #HTML #typescript
Вопрос:
У меня есть таблица в HTML, которая создается следующим образом:
<table id="tableID" onclick="getRowData()" class="table table-hover"></table>
Сначала он заполняется некоторыми исходными данными, которые могут придать ему примерно такой вид:
From Action To
a 1 b
a 0 a
Я хочу иметь возможность извлекать данные из произвольной строки, просто щелкнув по этой строке на веб-странице. Я также хочу иметь возможность извлекать индекс строки из этой строки. Например, если бы я хотел получить данные из первой строки, то я бы получил a 1 b
Как бы выглядела такая функция?
Комментарии:
1. Необходимо ли вам иметь
getRowData()
в элементе table?
Ответ №1:
Вы должны разместить свой обработчик щелчков по строкам, а не по таблице.
Поскольку ваша таблица генерируется динамически, прикрепление обработчиков щелчков из Typescript / JavaScript может быть проще, вот способ сделать это.
Используйте document.querySelector('#tableID')
для получения ссылки на вашу таблицу.
Затем есть два способа получить ссылку на строки и ячейки таблицы:
-
Используется
table.querySelectorAll('tbody td')
для запроса строк в таблице DOM. Затем используйтеrow.querySelectorAll('td')
для получения ячеек. -
Используйте table DOM API (см. Комментарий @H.B. ниже), чтобы избежать запроса DOM для каждой строки и каждой ячейки. С помощью этого метода вы можете получить строки с
table.tBodies[0].rows
и ячейки сrow.cells
.
Затем используйте element.addEventListener('click', handler)
, чтобы прикрепить обработчики щелчков к каждой строке.
Вот демонстрация JavaScript с подробными комментариями:
// get a reference to your table by id
// cast this to HTMLTableElement in TypeScript
const table = document.querySelector('#tableID');
// get all rows in the first table body
const rows = table.tBodies[0].rows;
// convert the rows to an array with the spread operator (...)
// then iterate over each row using forEach
Array.from(rows).forEach((row, idx) => {
// attach a click handler on each row
row.addEventListener('click', event => {
// get all cells in the row, convert them to an array with the spread operator (...)
// then for each cell, return its textContent by mapping on the array
const tds = Array.from(row.cells).map(td => td.textContent);
console.clear();
// Log the row index
console.log('row index:', idx);
// Log the tds content array
console.log('tds content:', ...tds);
// join the contents of the tds with a space and display the string
console.log('tds string:', tds.join(' '));
});
});
<table id="tableID">
<thead>
<tr><th>From</th><th>Action</th><th>To</th></tr>
</thead>
<tbody>
<tr><td>a</td><td>1</td><td>b</td></tr>
<tr><td>a</td><td>0</td><td>a</td></tr>
</tbody>
</table>
Кроме того, в вашем коде TypeScript не забудьте привести результат из document.querySelector('#tableID')
в HTMLTableElement
, чтобы получить правильный ввод:
const table: HTMLTableElement = document.querySelector('#tableID');
Комментарии:
1. Вы могли бы использовать table DOM API, который я бы предпочел всегда запрашивать. Т.е. чтобы получить строки =>
table.tBodies[0].rows
, чтобы получить ячейки =>row.cells
. (В TypeScript вам нужно привести результат первого запроса кHTMLTableElement
.)2. @H.B., Спасибо за комментарий, вы не возражаете, если я обновлю свой ответ?
3. Вовсе нет, продолжайте.
4. @jo_va когда я пытаюсь следовать вашему примеру кода, я получаю следующую ошибку
type <HTMLCollectionOf<HTMLTableRowElement> is not an array type
при попытке использовать оператор spread, […rows]. Каким должен быть тип?5. @jo_va большое спасибо, я думаю, что нашел ошибку. Я нацеливался на ES5, а не на ES6.