「特定のリスト項目だけスタイルを変えたい」「ネストされた要素の中から特定の要素だけを取得したい」——jQueryで子要素を操作する機会はWeb開発で頻繁に発生します。しかしchildren()とfind()の違いを正確に理解していないと、意図しない要素まで操作してしまうミスが起きます。
この記事では、jQueryの子要素操作の基本からchildren()・find()の使い分け・フィルタリング・イベント付与・パフォーマンスの注意点まで体系的に解説します。
jQueryの子要素とは
DOMにおける親子関係の基本
DOM(Document Object Model)はHTMLの構造をツリー状に表現したものです。あるHTML要素の直下にある要素を子要素、その外側にある要素を親要素と呼びます。
<!-- DOMの親子関係の例 -->
<ul id="parent"> <!-- 親要素 -->
<li class="child"> <!-- 直接の子要素 -->
<span>テキスト</span> <!-- 孫要素(childの子) -->
</li>
<li class="child"> <!-- 直接の子要素 -->
<span>テキスト2</span> <!-- 孫要素 -->
</li>
</ul>
子要素と子孫要素の違い
jQueryで子要素を操作する上で最も重要な概念が「子要素」と「子孫要素」の区別です。
| 用語 | 意味 | 取得メソッド |
|---|---|---|
| 直接の子要素 | 親要素の1階層直下にある要素のみ | children() |
| 子孫要素 | 親要素の配下にあるすべての要素(何階層下でも) | find() |
<div id="grandparent">
<div id="parent"> <!-- #grandparentの直接の子 -->
<p id="child"> <!-- #grandparentの孫 / #parentの直接の子 -->
<span id="grandchild"></span> <!-- #grandparentのひ孫 -->
</p>
</div>
</div>
子要素操作の用途(スタイル変更・イベント付与など)
- スタイル変更: タブ切り替えでアクティブな子要素だけスタイルを変える
- イベント付与: リスト項目のクリックイベントを子要素にまとめて設定する
- 要素の追加・削除: 動的に子要素を増減させるフォームや動的リストの制御
- 値の取得・変更: フォーム内の入力フィールドの値をまとめて取得する
children()メソッドの基本
特定の直接子要素を取得
基本構文:$(selector).children()
children()は選択した要素の直接の子要素のみを取得します。引数なしで使うと、すべての直接の子要素を返します。
// HTML構造
// <ul id="menu">
// <li>ホーム</li>
// <li>About</li>
// <li>Contact</li>
// </ul>
// #menuの直接の子要素(li)をすべて取得
const items = $('#menu').children();
console.log(items.length); // 3
// 取得した子要素にスタイルを適用
$('#menu').children().css('color', 'blue');
// テキスト内容を確認
$('#menu').children().each(function() {
console.log($(this).text());
// "ホーム"
// "About"
// "Contact"
});
jQueryのchildren()メソッドの詳しい使い方はこちらの記事も参考になります。
フィルター指定で条件に合う子要素のみ取得
$(selector).children(‘.className’)
children()の引数にセレクターを渡すことで、条件に一致する直接の子要素だけを絞り込めます。
// HTML構造
// <ul id="list">
// <li class="active">アイテム1</li>
// <li>アイテム2</li>
// <li class="active">アイテム3</li>
// <li>アイテム4</li>
// </ul>
// class="active"の直接の子要素のみ取得
$('#list').children('.active').css('font-weight', 'bold');
// アイテム1とアイテム3が太字になる
// タグ名でフィルタリング
$('#list').children('li').css('border', '1px solid gray');
// 複数条件(カンマ区切り)
$('#list').children('.active, :first').css('background', '#f0f0f0');
// 属性セレクターでフィルタリング
$('#form').children('input[type="text"]').val('');
find()メソッドとの違い
子孫全てを検索するfind()
$(selector).find(‘li’)
find()は選択した要素の配下にあるすべての子孫要素を検索します。何階層深くにある要素でも取得できます。
// HTML構造
// <div id="nav">
// <ul>
// <li>ホーム</li>
// <li>
// <ul>
// <li>サブ1</li>
// <li>サブ2</li>
// </ul>
// </li>
// </ul>
// </div>
// #navの配下にあるすべてのliを取得(ネスト含む)
const allLi = $('#nav').find('li');
console.log(allLi.length); // 4(すべてのliを取得)
// children()との比較
const directLi = $('#nav').children('li');
console.log(directLi.length); // 0(#navの直接の子はulのみ)
// findでクラスを検索
$('#nav').find('.active').css('color', 'red');
children()は直接の子のみ、find()は全階層対象
2つのメソッドの違いを視覚的に理解するためのコード例です。children()とfind()の動作の違いと使い分けはこちらの記事も参考になります。
// HTML構造
// <div id="container">
// <p class="text">直接の子</p>
// <div>
// <p class="text">孫要素</p>
// </div>
// </div>
// children(): 直接の子 .text のみ(1件)
$('#container').children('.text').css('color', 'blue');
// → "直接の子"のみが青くなる
// find(): すべての .text(2件)
$('#container').find('.text').css('color', 'red');
// → "直接の子"と"孫要素"の両方が赤くなる
用途に応じた使い分け
| メソッド | 取得範囲 | 向いている場面 |
|---|---|---|
children() |
直接の子要素のみ | 特定の親の直下だけ操作したい・ネストした同名要素を区別したい |
find() |
全子孫要素 | 階層が複数あっても特定の要素をすべて取得したい |
判断の基準: 「ネストされた構造の中に同名のクラスや要素がある場合」はchildren()で直接の子だけに絞り、「どの階層にあっても全部取得したい場合」はfind()を使うと覚えてください。
children()の応用操作
子要素のスタイル変更
CSSやクラスの追加・削除
子要素のスタイルをjQueryで動的に変更する実践的なパターンです。
// CSSプロパティを直接変更
$('#list').children('li').css({
'padding': '10px',
'border-bottom': '1px solid #eee',
'list-style': 'none'
});
// クラスの追加
$('#list').children('li').addClass('list-item');
// クラスの削除
$('#list').children('li').removeClass('hidden');
// クラスのトグル(あれば削除・なければ追加)
$('#list').children('li').toggleClass('active');
// 特定のインデックスの子要素だけクラス変更
$('#list').children('li').eq(0).addClass('first-item');
// タブ切り替えの例: アクティブな子要素だけスタイル変更
$('#tabs').children('button').on('click', function() {
$(this).siblings().removeClass('active'); // 兄弟要素のactiveを解除
$(this).addClass('active'); // クリックした要素にactiveを付与
});
子要素にイベントを付与
click、hoverなど
jQueryで子要素にイベントを付与する方法の詳細はこちらの記事も参考になります。
// クリックイベントを子要素にまとめて付与
$('#menu').children('li').on('click', function() {
// クリックされた要素のテキストを取得
const text = $(this).text();
console.log(text + 'がクリックされました');
// クリックされた要素をハイライト、兄弟は解除
$(this).addClass('selected').siblings().removeClass('selected');
});
// hoverイベント(マウスオーバー・アウト)
$('#gallery').children('.item').on({
mouseenter: function() {
$(this).find('.caption').fadeIn(200);
},
mouseleave: function() {
$(this).find('.caption').fadeOut(200);
}
});
// 複数の子要素に同時にイベント付与
$('#form').children('input, select, textarea').on('change', function() {
console.log($(this).attr('name') + 'が変更されました');
});
子要素の削除や挿入
.remove() や .append() の活用
// 特定の子要素を削除
$('#list').children('.remove-target').remove();
// 最初の子要素を削除
$('#list').children(':first').remove();
// 子要素を末尾に追加
$('#list').append('<li>新しい項目</li>');
// 子要素を先頭に追加
$('#list').prepend('<li>先頭に追加</li>');
// 特定の子要素の前後に挿入
$('#list').children().eq(1).before('<li>2番目の前に挿入</li>');
$('#list').children().eq(1).after('<li>2番目の後に挿入</li>');
// すべての子要素を削除して入れ替え
$('#list').empty().append('<li>リセット後の項目1</li><li>リセット後の項目2</li>');
フィルタリングや条件指定
:first、:last、:eq(index) を使った指定
// HTML
// <ul id="list">
// <li>アイテム1</li>
// <li>アイテム2</li>
// <li>アイテム3</li>
// <li>アイテム4</li>
// </ul>
// 最初の子要素
$('#list').children(':first').css('font-weight', 'bold');
// または(パフォーマンスが良い方法)
$('#list').children().first().css('font-weight', 'bold');
// 最後の子要素
$('#list').children(':last').css('border-bottom', 'none');
// または
$('#list').children().last().css('border-bottom', 'none');
// インデックス指定(0始まり): 3番目の要素(インデックス2)
$('#list').children(':eq(2)').css('background', '#f0f0f0');
// または
$('#list').children().eq(2).css('background', '#f0f0f0');
// 偶数・奇数の子要素(テーブルのしまし模様など)
$('#list').children(':even').css('background', '#f9f9f9');
$('#list').children(':odd').css('background', '#ffffff');
filter() メソッドで条件を追加
filter()は一度取得した要素のセットをさらに絞り込むメソッドです。filter()とchildren()を組み合わせた子要素操作の詳細はこちらの記事も参考になります。
// children()で取得後にfilter()で絞り込む
$('#list').children().filter('.active').css('color', 'red');
// 関数を使った動的なフィルタリング
$('#list').children().filter(function(index) {
// テキストが5文字以上の要素のみ
return $(this).text().length >= 5;
}).css('background', '#ffe');
// 特定の属性を持つ要素のみ
$('#form').children().filter('[data-required]').css('border-color', 'red');
// filter()とnot()の組み合わせ
// activeクラスを持たない子要素を取得
$('#list').children().not('.active').css('opacity', '0.5');
特定属性やクラスにマッチする子要素のみ操作
// data属性でフィルタリング
$('#products').children('[data-category="food"]').show();
$('#products').children('[data-category!="food"]').hide();
// 複数クラスの組み合わせ
$('#items').children('.item.featured').css('border', '2px solid gold');
// 属性の部分一致
$('#list').children('[class*="highlight"]').css('background', 'yellow');
// :not()で否定条件
$('#list').children('li:not(.disabled)').on('click', function() {
// disabledクラスのないliだけクリックイベント発火
console.log($(this).text());
});
注意点とベストプラクティス
children()は直接の子のみ取得すること
children()はネストされた要素には作用しません。意図せずfind()の代わりにchildren()を使うと、要素が取得できず処理が動かない原因になります。取得できた要素が0件の場合はchildren()/find()の使い分けを確認してください。
// よくあるミス
// <div id="container">
// <div>
// <p class="target">ここを操作したい</p>
// </div>
// </div>
// 誤り: pは直接の子ではないため取得できない
$('#container').children('.target').css('color', 'red'); // 効果なし
// 正しい: find()で全子孫を検索
$('#container').find('.target').css('color', 'red'); // 正常に動作
DOM構造の変化に注意
動的にDOMが変化する場合、取得した子要素の参照が古くなることがあります。
// 悪い例: DOM変化前に取得した参照を使い続ける
const items = $('#list').children('li');
$('#list').append('<li>新しい項目</li>');
console.log(items.length); // 古い件数のまま(新しい項目は含まれない)
// 良い例: 操作のたびに再取得する
function updateItems() {
// 処理のたびにchildren()を再実行
$('#list').children('li').each(function(index) {
$(this).text((index + 1) + '番目の項目');
});
}
// DOM変更後に再実行
$('#list').append('<li></li>');
updateItems(); // 最新のDOMに基づいて処理
大量の子要素操作はパフォーマンス考慮
// 非効率な例: ループ内でDOMを繰り返し操作
$('#list').children('li').each(function() {
$(this).css('color', 'red'); // 1要素ごとに再描画が発生
});
// 効率的な例1: jQueryのメソッドチェーンで一括適用
$('#list').children('li').css('color', 'red'); // 一括適用
// 効率的な例2: DocumentFragmentを使った大量挿入
const fragment = $(document.createDocumentFragment());
for (let i = 0; i < 100; i++) {
fragment.append('<li>アイテム' + i + '</li>');
}
$('#list').append(fragment); // 1回のDOM操作で挿入
イベント委譲と組み合わせると効率的
動的に追加される子要素にはイベント委譲(Event Delegation)を使うことで、個別にイベントを付与する必要がなくなります。
// 非効率: 既存の子要素にのみイベントが付与される(動的追加分は対象外)
$('#list').children('li').on('click', function() {
console.log($(this).text());
});
// 効率的: イベント委譲で動的追加された子要素にも適用される
$('#list').on('click', 'li', function() {
// #listの子孫のliがクリックされたときに発火
console.log($(this).text());
});
// 新しいliを追加してもイベントが自動的に適用される
$('#list').append('<li>動的に追加された項目</li>');
まとめ
children()で直接子要素、find()で全子孫要素を取得
jQueryの子要素操作で最も重要な使い分けはchildren()とfind()です。
| メソッド | 取得範囲 | 代表的な使い方 |
|---|---|---|
children() |
直接の子要素のみ | $('#parent').children('.item') |
find() |
全子孫要素 | $('#parent').find('.item') |
filter() |
取得済み要素の絞り込み | $('#parent').children().filter('.active') |
スタイル変更・イベント付与・要素追加・削除に活用
- 子要素のスタイルは
children().css()・addClass()・removeClass()で一括変更できる - クリックや hover などのイベントは
children().on()でまとめて付与できる - 動的に変化するDOMにはイベント委譲(
parent.on('click', 'child', fn))を使う - 大量の子要素操作は一括処理とDocumentFragmentでパフォーマンスを改善できる
フィルターや条件指定で柔軟な子要素操作が可能
:first・:last・:eq(n)などの疑似セレクターや、filter()・not()を組み合わせることで、複雑な条件での子要素操作も簡潔に記述できます。children()とfind()の違いを正確に理解した上で、用途に合わせて使い分けることがjQueryでの効率的なDOM操作の基本です。

