Web制作の現場で、テーブル(表)を扱う機会は少なくありません。特に管理画面やデータ一覧など、ユーザーがデータを動的に操作するUIを構築する際には、単にHTMLでテーブルを組むだけでなく、JavaScriptによる高度な制御が求められます。
そんな時、「テーブルの行」を操作するための強力なインターフェースとなるのが、今回ご紹介する`HTMLTableRowElement`です。多くのWebデザイナーは「`tr`要素」として認識していますが、実はこの`tr`要素、ただのHTML要素ではない、特別な機能を持っているのです。
`HTMLTableRowElement`とは?基本から実務へ
`HTMLTableRowElement`は、HTMLの`
例えば、JavaScriptで`document.getElementById(‘myTable’).rows[0]`のようにテーブルの行を取得したり、イベントリスナー内で`event.target.closest(‘tr’)`を使ってクリックされた要素の親である`tr`要素を取得したりすると、それは`HTMLTableRowElement`のインスタンスとなります。
この`HTMLTableRowElement`は、単なる汎用的な`HTMLElement`とは異なり、テーブルの行に特化した便利なプロパティやメソッドを多数持っています。これらを深く理解し、使いこなすことが、実務における効率的で堅牢なテーブル操作の鍵となります。
`cells`コレクションを使いこなす:行内のセルにアクセス
`HTMLTableRowElement`が持つプロパティの中でも、実務で最も頻繁に利用するのが`cells`コレクションでしょう。これは、その行に含まれるすべての`
具体例1: 行の内容をまとめて取得・更新する
データ一覧で特定の行が選択された際に、その行のデータをまとめて取得し、詳細表示用のフォームにセットする、といったシナリオを考えてみましょう。
const targetRow = document.getElementById(‘data-table’).rows[1]; // 2行目を取得
const rowData = [];
for (let i = 0; i < targetRow.cells.length; i++) {
rowData.push(targetRow.cells[i].textContent);
}
console.log('選択された行のデータ:', rowData);
// => [‘商品名A’, ‘1000円’, ‘在庫あり’] のような配列が取得できる
このように`cells`をループすることで、その行のデータを簡潔に抽出できます。
具体例2: インライン編集機能の実装
管理画面などで、テーブルの行を直接クリックして編集できる「インライン編集」機能は、ユーザー体験を向上させる強力な手法です。これも`cells`コレクションを活用することで実現できます。
const dataTable = document.getElementById(‘data-table’);
dataTable.addEventListener(‘click’, function(event) {
const targetCell = event.target.closest(‘td’);
if (!targetCell) return; // td要素以外をクリックした場合は処理しない
const targetRow = targetCell.closest(‘tr’);
if (!targetRow || targetRow.querySelector(‘input’)) return; // 既に編集中の行は処理しない
// 編集モードに切り替え
for (let i = 0; i < targetRow.cells.length; i++) {
const cell = targetRow.cells[i];
const originalText = cell.textContent;
cell.innerHTML = ``;
}
// 例: 保存ボタンなどを追加して、編集後にデータを送信する処理
const saveButton = document.createElement(‘button’);
saveButton.textContent = ‘保存’;
saveButton.onclick = function() {
const updatedData = [];
for (let i = 0; i < targetRow.cells.length; i++) {
const input = targetRow.cells[i].querySelector('input');
if (input) {
updatedData.push(input.value);
}
}
console.log('更新されたデータ:', updatedData);
// ここでAJAXリクエストなどでサーバーにデータを送信する
alert('データが保存されました。');
// 編集モードを終了し、元の表示に戻す
for (let i = 0; i < targetRow.cells.length; i++) {
const input = targetRow.cells[i].querySelector('input');
if (input) {
targetRow.cells[i].textContent = input.value;
}
}
this.remove(); // 保存ボタンを削除
};
targetRow.appendChild(saveButton);
});
上記は簡略化した例ですが、`cells`を通じて各セルにアクセスし、その中身を`input`要素に置き換えることで、動的なインライン編集UIを構築できます。
行の動的な追加と削除:`insertCell()`と`deleteCell()`
`HTMLTableRowElement`は、その行内のセルを動的に操作するメソッドも提供しています。
- `tr.insertCell(index)`: 指定したインデックスの位置に新しいセル(`
`)を追加します。`index`を省略するか、`-1`を指定すると末尾に追加されます。 - `tr.deleteCell(index)`: 指定したインデックスのセルを削除します。
これらのメソッドは、「既存のテーブルの行に新しい列(セル)を追加したい」「特定の列を削除したい」といった場合に非常に便利です。
例えば、ユーザーの権限に応じて表示する列を切り替えたり、あるいは一時的に情報表示用のセルを挿入したりする際に役立ちます。ただし、テーブル全体の列数との整合性や、`colspan`を使用している場合の挙動には注意が必要です。
`rowIndex`と`sectionRowIndex`:行の位置を正確に把握する
`HTMLTableRowElement`には、その行がテーブル内でどの位置にあるかを示すプロパティもあります。
- `tr.rowIndex`: テーブル全体における行のインデックス(0から始まる)。`
`、`
`、`
`の区別なく、テーブル全体での上からの順番を示します。
- `tr.sectionRowIndex`: その行が含まれるセクション(` `、` `、` `)内でのインデックス(0から始まる)。
「テーブル全体で何番目の行か」と「`
`の中で何番目の行か」を明確に区別して取得できるため、ソート処理や、特定の行を識別してCSSを適用する際などに非常に重宝します。実践的なヒント:パフォーマンスとアクセシビリティ
動的なテーブル操作を行う上で、常に意識しておきたいのがパフォーマンスとアクセシビリティです。
- パフォーマンス: 大量の行やセルを操作する際は、DOM操作の回数を最小限に抑える工夫が必要です。例えば、多数のセルを追加する場合は、`DocumentFragment`を使って一度にDOMにアタッチしたり、非表示の行をスタイルで切り替える(`display: none;`)ことで、DOMの再描画コストを削減できます。
- アクセシビリティ: 行の追加、削除、更新といった動的な変更は、スクリーンリーダーの利用者には伝わりにくいことがあります。`aria-live`属性を使って変更をアナウンスしたり、意味のある`
`要素と`scope`属性を適切に利用してテーブル構造を明確にしたりするなど、ユーザー補助技術への配慮を忘れないでください。 まとめ
`HTMLTableRowElement`は、単なるHTMLの`
`要素というだけでなく、その行をJavaScriptからパワフルに操作するための豊富な機能を持ったオブジェクトです。 `cells`コレクションによる行内のセルへのアクセス、`insertCell()`や`deleteCell()`による動的なセル操作、そして`rowIndex`や`sectionRowIndex`による位置情報の取得。これらを使いこなすことで、複雑な要件が求められる実務においても、効率的かつ堅牢なテーブル操作を実現できます。
ぜひ、日々の開発で`HTMLTableRowElement`の可能性を探り、ユーザーにとってより使いやすい、動的なWeb UIの構築に役立ててください。
タイトルとURLをコピーしました
- `tr.sectionRowIndex`: その行が含まれるセクション(` `、` `、` `)内でのインデックス(0から始まる)。

コメント