タイトル: .eq()
SEOタイトル: jQuery .eq() 完全ガイド(index 指定・first/last との違い・性能)
| この記事の要点 |
|
.eq() の基本
.eq(index) は、jQuery オブジェクト内の指定 index の要素 1 つだけを含む新しい jQuery オブジェクトを返します。
- 0番目
- 1番目
- 2番目
- 3番目
$('#list li').eq(0).text(); // "0番目"
$('#list li').eq(1).text(); // "1番目"
$('#list li').eq(3).text(); // "3番目"
// 範囲外
$('#list li').eq(10); // 空の jQuery オブジェクト
$('#list li').eq(10).length; // 0
// 負の index = 末尾から数える
$('#list li').eq(-1).text(); // "3番目"
$('#list li').eq(-2).text(); // "2番目"
// チェーン操作
$('#list li').eq(0).addClass('first').css('color', 'red');
類似メソッドとの違い
| メソッド | 戻り値 | 用途 |
|---|---|---|
.eq(i) | jQuery オブジェクト | index 指定で 1 要素 |
.first() | jQuery オブジェクト | = .eq(0)、可読性◎ |
.last() | jQuery オブジェクト | = .eq(-1) |
.get(i) | 生 DOM 要素 | VanillaJS API を使いたいとき |
[i] | 生 DOM 要素 | .get(i) と同じ |
.slice(start, end) | jQuery オブジェクト | 範囲指定で複数 |
.filter(sel|fn) | jQuery オブジェクト | 条件で絞り込み |
const $li = $('#list li');
// jQuery オブジェクトとして取り出す(チェーン可)
$li.eq(0).addClass('selected');
$li.first().addClass('selected'); // 同じ
// 生 DOM として取り出す(VanillaJS API を使うとき)
const el = $li.get(0); // = $li[0]
el.scrollIntoView();
el.dataset.foo = 'bar';
// 注意: 生 DOM 要素に jQuery メソッドは使えない
// $li.get(0).addClass('x'); // ❌ TypeError
// jQuery で包み直せばOK
$($li.get(0)).addClass('x'); // ✅
:eq() セレクタフィルタとの違い
jQuery には :eq(n) というセレクタフィルタもありますが、性能とお作法の理由から .eq() メソッドの方が推奨されます:
// 同じ結果になる 2 通り
$('#list li:eq(0)').text(); // セレクタフィルタ
$('#list li').eq(0).text(); // メソッド(★推奨)
/* なぜメソッドが推奨か:
* 1. :eq() は jQuery 独自拡張で querySelectorAll では使えない
* → 内部で全要素を取得後にフィルタリング = 遅い
* 2. .eq() は標準 CSS セレクタで取得済の集合に対する操作 = 速い
* 3. :eq() は CSS Selectors Level 4 の :nth-child とも違う挙動で紛らわしい
*/
.slice() で複数要素を範囲取得
const $li = $('#list li'); // 4 要素
$li.slice(0, 2); // index 0,1 の 2 要素
$li.slice(1); // index 1 以降 全部 (1,2,3)
$li.slice(-2); // 末尾 2 要素 (2,3)
$li.slice(1, -1); // 中間(1,2)
// 用途例: 最初と最後を除く
$li.slice(1, -1).addClass('middle');
each / map との組み合わせ
$('#list li').each(function(index, el) {
// this = el = 生 DOM
// $(this) = $(el) = 1 要素の jQuery オブジェクト
console.log(index, $(this).text());
if (index % 2 === 0) {
$(this).addClass('even');
}
});
// map で値の配列を作る
const texts = $('#list li').map(function() {
return $(this).text();
}).get(); // .get() で生配列に
// → ["0番目", "1番目", "2番目", "3番目"]
Vanilla JavaScript での同等処理
| jQuery | Vanilla JS |
|---|---|
$('li').eq(0) | document.querySelectorAll('li')[0] |
$('li').first() | document.querySelector('li') |
$('li').last() | [...document.querySelectorAll('li')].at(-1) |
$('li').eq(-1) | document.querySelectorAll('li').item(-1) ❌(item は -1 非対応)[...nodeList].at(-1) ✅ |
$('li').slice(1, 3) | [...document.querySelectorAll('li')].slice(1, 3) |
$('li').each((i, el) => ...) | document.querySelectorAll('li').forEach((el, i) => ...) |
// 注意点: NodeList は Array ではないので
const nodes = document.querySelectorAll('li');
nodes[0]; // ✅ index アクセス OK
nodes.length; // ✅
nodes.forEach(el => ...); // ✅ ES2015 以降は forEach OK
// nodes.map(...) // ❌ NodeList に map なし
[...nodes].map(...); // ✅ スプレッドで Array に
Array.from(nodes).map(...); // ✅
nodes.item(2); // ✅ index アクセスの古い書き方
パフォーマンス
| 書き方 | 速度 | 備考 |
|---|---|---|
$('li').eq(0) | 速い | querySelectorAll 後に index 取得 |
$('li:eq(0)') | 遅い | jQuery 拡張セレクタの解析が入る |
$('li').first() | 速い | = eq(0) |
$('li:first') | 遅い | = li:eq(0) |
document.querySelector('li') | 最速 | Vanilla(jQuery 経由しない) |
大量要素(1000 件超)で頻繁にループするなら、jQuery オブジェクトを 1 回作って .eq() でアクセス、または Vanilla の querySelectorAll + index を使うのが鉄則です。
よくある用途
// タブの切替: クリックされた index を active に
$('.tab').on('click', function() {
const i = $(this).index(); // クリックされた要素の index
$('.tab').removeClass('active');
$('.tab').eq(i).addClass('active'); // 該当タブを active
$('.panel').hide();
$('.panel').eq(i).show(); // 該当パネルを表示
});
// カルーセル: 現在 index を保持
let current = 0;
const $slides = $('.slide');
function showSlide(i) {
current = (i + $slides.length) % $slides.length;
$slides.hide();
$slides.eq(current).show();
}
$('.next').on('click', () => showSlide(current + 1));
$('.prev').on('click', () => showSlide(current - 1));
// テーブルの偶数行に色を付ける
$('tr').each((i, el) => {
if (i % 2 === 0) $(el).addClass('even');
});
FAQ
Q: .eq(0) が undefined を返す
A: 範囲外の場合は空の jQuery オブジェクト(length === 0)を返します。.text() 等は空文字。判定するには .length をチェック。
Q: [0] と .get(0) の違い
A: 同じ。どちらも生 DOM を返します。.get() は配列化(.get() 引数なし)にも使えるので柔軟。
Q: .index() と .eq() の関係
A: .index() は「自分が兄弟の中で何番目か」を返すゲッタ。.eq(i) は「i 番目を取り出す」セッタ。クリック処理で組み合わせると便利。