jQueryで何かしたい時にまずセレクタで該当要素を指定すると思いますが、要素にidやclassがついていなくても特定の条件を持つ要素として指定できたり、奇数・偶数・n番目の要素を指定できたりと、セレクタには様々な指定方法があります。ただ中には利用頻度が低くていざ使える場面がきても忘れしてしまっていたり、未だに使う度にググったりするものも幾つかあるので、セレクタに関しての復習兼ねた備忘録です。また、併せて同じく使用する機会が多いthisに関することやセレクタで指定した要素の親要素や子要素を指定する方法も書いておこうと思います。
jQuery:セレクタや要素指定に関する備忘録 目次
1. 各種セレクタ
ユニバーサル
全ての要素に対して何かをしたい時。
$("*")
要素指定
div
やp
など、特定の要素を指定したい時。
$("element")
特定のidが指定されている要素
$("#id")
特定のclassが指定されている要素
$(".class")
複数の要素
複数の要素に対して指定する時は「,」(カンマ)区切りで記述します。
$("elementA, elementB, elementC")
子孫セレクタ
elementA 内にある elementB を指定。
$("elementA elementB")
子セレクタ
elementA 直下にある elementB を指定。
$("elementA > elementB")
隣接セレクタ
elementA に隣接している elementB を指定。
$("elementA + elementB")
間接セレクタ
elementA 以降に兄弟要素として出てくる elementB を指定。
$("elementA ~ elementB")
特定の属性を持つ要素
$("[attribute]")
特定の属性が指定した値を持つ要素
例えばinput
要素が沢山あるけどtype="text"
のみ何かしたい時は、$("input[type='text']")
で指定できます。
$("[attribute='value']")
特定の属性が指定した値を持たない要素
$("[attribute!='value']")
特定の属性で値が前方一致する要素
このセレクタは正確には全く違うclassやnameなどが指定されているけれど同じ処理をしたいという時に使えて、あとに出てくる後方一致や部分一致と併せて覚えておくと非常に便利です。
$("[attribute^='value']")
例えばclass
やname
特定の属性で値が後方一致する要素
$("[attribute$='value']")
特定の属性で値が部分一致する要素
$("[attribute*='value']")
複数の属性を持つ要素
$("[attributeA][attributeB]")
指定した要素の最初の要素
$("element:first")
指定した要素の最後の要素
$("element:last")
指定した要素の奇数番目の要素
$("element:odd")
指定した要素の偶数番目の要素
$("element:even")
指定した要素のn番目の要素
$("element:eq(n)")
指定した要素のn番目より前の要素
$("element:lt(n)")
指定した要素のn番目より後の要素
$("element:gt(n)")
最初・最後・n番目などの指定方法は他にも以下のようなものがあり、nthから始まるものはn番目指定や偶数・奇数指定が可能だったりと、より絞った形で指定が可能になります。
- :first-child
- :first-of-type
- :last-child
- :last-of-type
- :only-child
- :only-of-type
- :nth-child()
- :nth-last-child()
- :nth-last-of-type()
- :nth-of-type()
disabled状態の要素
$("element:disabled")
ラジオボタンやチェックボックスのチェック状態時
$("element:checked")
オプションの選択状態時
$("element:selected")
非表示状態の要素
$("element:hidden")
表示状態の要素
$("element:visible")
指定した条件以外の要素
$("element:not(selector)")
アニメーション状態の要素
$("element:animated")
上記で紹介しているフィルタはほんの一部で、他にも特定の要素を持つ要素を指定できる:has()
や特定のテキストを持つ要素を指定できる:contains()
、h1やh2といった見出し要素を指定する:header
などもあります。
ちなみに、フォーム周りで使えるものとして全てのinput
・textarea
・select
・button
要素を指定する:input
やtype="text"
の要素を指定する:text
というものもあるのですが、これらは現在では非推奨となっており、例えば:input
の場合は属性セレクタを使用して$("[type='text']")
という記述を用いることが推奨されています。
様々なセレクタを紹介してきましたが、より詳しい説明や簡単なデモ、ここで紹介していないセレクタなどは下記公式サイトのセレクタページで確認できます。
2. thisの使い方
例えばクリックされた要素に対して何か行いたい時など、普通にセレクタで要素指定してしまうと場合によっては意図しない箇所まで適用されてしまうということがあるのですが、それを防ぐために this を利用することがあります。
具体的には先ほど例に出したクリックされた要素にだけ行いたい時は下記のように記述します。
jQuery
$('div').on('click', function() {
$(this).css('background-color', 'black');
});
上記は「div
要素をクリックすると背景色を黒に変更する」という記述をしたものになるのですが、上記ソースで$(this)
の部分を$('div')
と記述した場合、div
要素が他にもあった場合は他のdiv
要素の背景色も変更されてしまいます。
それを上記のように$(this)
を用いる形にすれば、そのクリックしたdiv
要素のみ背景色を変更させることができます。
thisの親要素や子要素を指定したい時
詳しくは後述しますが、.parent()
や.children()
というメソッドを使用すれば、thisを用いて親要素や子要素への指定が可能になります。
例えばthisで指定された要素の親要素を指定したい時は下記のように記述します。
jQuery
$(this).parent();
また、thisで指定された要素の中にあるp
要素を指定したい時は下記のように記述します。
jQuery
$(this).children('p');
もしくは下記のような記述も可能で、こちらの場合は子要素だけでなく孫要素も指定することができます。
jQuery
$('p', this);
3. 親要素や子要素などを指定
thisの説明時に少し出てきましたが、jQueryには.parent()
や.children()
といったメソッドが用意されており、これらを用いることでセレクタで指定した要素の親・子・孫・兄弟といった要素を指定することができます。
一応簡単な例も併せて紹介はしていますが、実際に動きを確認できるデモが公式サイトに掲載されているので、それを確認するとよりわかりやすいと思います。
親要素の指定
.parent()
直近の親要素を指定するもので、例えば.parent('div')
のように記述すれば直近のdiv
要素ということになります。
例として下記のようなHTMLがあり、p
をセレクタに指定している時に親要素であるdiv
を指定したい時には下記のように記述します。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<div>
<p></p>
</div>
jQuery
$('p').parent();
.parents()
.parent()
では指定できなかった更に上にある親要素まで指定が可能で、こちらも.parents('element')
のような記述をすることで更に絞り込んだ指定が可能です。
例として下記のようなHTMLがあり、span
をセレクタに指定した時にdiv
を指定したい時には下記のように記述します。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<div>
<p>
<span></span>
</p>
</div>
jQuery
$('span').parents('div');
.closest()
こちらも親要素を指定したい時に便利なメソッドで、指定した条件に最も近い(最初にマッチした)ものを指定することが可能です。
例として下記のようなHTMLがあり、p
をセレクタに指定して.closest()
を使用した場合は、複数親要素としてあるdiv
要素の中から一番近いdiv class="baz"
が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<div class="foo">
<div class="bar">
<div class="baz">
<p></p>
</div>
</div>
</div>
jQuery
$('p').closest();
子・孫要素の指定
.children()
セレクタの子要素を指定することができるメソッドで、.children('element')
のような指定もできます。
例として下記のようなHTMLがあり、div class="foo"
をセレクタに指定して.children()
を使用した場合は、div class="bar"
が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<div class="foo">
<div class="bar">
<div class="baz">
<p></p>
</div>
</div>
</div>
jQuery
$('.foo').children();
.find()
こちらはセレクタの子要素だけでなく孫要素も指定できるメソッドで、先ほどのサンプルソースで.children()
の時には指定できなかったp
要素なども指定することが可能になります。
例として下記のようなHTMLがあり、div class="foo"
をセレクタに指定して、その中にあるp
要素を指定したい場合は、下記のように記述します。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<div class="foo">
<div class="bar">
<div class="baz">
<p></p>
</div>
</div>
</div>
jQuery
$('.foo').find('p');
兄弟要素の指定
.next()
メソッド名からしてわかりやすいですが、セレクタで指定した要素の次にある要素を指定することができます。
例として下記のようなHTMLがあり、class="foo"
が指定されているli
(3つ目)をセレクタに指定して.next()
を使用した場合は、その次にある4つ目のli
要素が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<ul>
<li></li>
<li></li>
<li class="foo"></li>
<li></li>
<li></li>
</ul>
jQuery
$('.foo').next();
.nextAll()
こちらはセレクタで指定した要素の次以降にある全ての兄弟要素を指定することができます。
例として下記のようなHTMLがあり、class="foo"
が指定されているli
(3つ目)をセレクタに指定して.nextAll()
を使用した場合は、その次以降にある4つ目と5つ目のli
要素が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<ul>
<li></li>
<li></li>
<li class="foo"></li>
<li></li>
<li></li>
</ul>
jQuery
$('.foo').nextAll();
.prev()
.next()
の反対で、セレクタで指定した要素の前にある要素を指定することができます。
例として下記のようなHTMLがあり、class="foo"
が指定されているli
(3つ目)をセレクタに指定して.prev()
を使用した場合は、その前にある2つ目のli
要素が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<ul>
<li></li>
<li></li>
<li class="foo"></li>
<li></li>
<li></li>
</ul>
jQuery
$('.foo').prev();
.prevAll()
こちらは.nextAll()
の反対で、セレクタで指定した要素の前にある全ての兄弟要素を指定することができます。
例として下記のようなHTMLがあり、class="foo"
が指定されているli
(3つ目)をセレクタに指定して.prevAll()
を使用した場合は、その前にある1つ目と2つ目のli
要素が指定されることになります。
※赤文字がセレクタ、緑文字が対象要素になります。
HTML
<ul>
<li></li>
<li></li>
<li class="foo"></li>
<li></li>
<li></li>
</ul>
jQuery
$('.foo').prevAll();
上記でセレクタの親や子にあたる要素を指定できるメソッドを幾つかあげましたが、同じようなことができるメソッドはここで紹介した以外にもあり、例えばテキストノードも含めた全子要素を取得できる.contents()
やCSSのpositiion
指定がされている親要素などを取得することができる.offsetParent()
といったものもあります。
個人的に上で紹介したものに比べるとそこまで多用するものではないので今回は大きく紹介しませんでしたが、場合によっては非常に便利だと感じるものでもあるので、とりあえずそういったメソッドもあるということだけでも頭に入れておきたいですね :)