見出し画像

ブックマークレットで始める業務改善⑧ CSSセレクターを使いこなそう

前回はこちら。

操作したい要素を捕まえるためには、適切にCSSセレクターを書かなければなりません。いろんな方法が用意されているので、それをうまく組み合わせて目的を達成しましょう。

今回は詰め込み学習です。がんばってください!🐶


ブックマークレットを作成する際によく使われるCSSセレクターについて解説します。ただしその前に、HTMLについてざっくり解説します。

HTMLのざっくり解説

WebページはHTMLという言語で書かれています。<body>, <input>のような< >で囲まれたタグが大量に並べられています。

HTMLとブラウザーでの表示

</body> のように / で始まるタグは、その要素が終わる場所を示しています。これまで「要素」という言葉を使ってきましたが、例えばbody要素なら、HTMLの世界では<body>から始まり</body>で終わる部分(上の図だと12~34行)を示しています。これが要素の正体です。

タグにはたくさんの種類があります。ブックマークレットでよく使うのは、<input><div><table><a><button>などです。出てきたときに、どういう意味を持つタグなのかを調べると勉強になるでしょう。

ひとつの要素の中にもたくさんのタグが並んでいます。HTMLは全体として親子構造(階層構造)を作っています。最上位のhtml要素を除き、すべての要素は親をひとつだけ持っています。親子関係を利用して要素を捕まえるのも重要なテクニックです。

上図のHTMLの親子構造

ひとつの要素(タグ)に注目すると、xxx="yyy"という形で付加情報が書かれています。これを属性と言います。= の左側は属性名、右側は属性値です。

属性

属性にはさまざまな種類がありますが、ブックマークレットを作るときはid属性とclass属性が重要です。input要素を触るならtype属性とname属性も力になります。

ではHTMLの説明はこのくらいにして、本題のCSSセレクターの話を始めましょう。

CSSセレクター

document.querySelector( ) や document.querySelectorAll( )で使える検索条件のうち、よく使うものを以下に並べています。これらは組み合わせて使えます。例えば "div.sideMenu > p" は、「sideMenuというクラスを持つdiv要素の直接の子になっているp要素」を選択できます。

# IDセレクター

指定したID属性を持つ要素を選択します。原則としてひとつのページの中で、ひとつのIDはひとつの要素にしか付いていないはずですが、それを守っていないwebページもあるのでご注意を。

document.querySelector("#myElement")

[] 属性セレクター

指定した属性を持つ要素を選択します。属性名だけでも行けますし、属性値を指定することもできます。

document.querySelectorAll("[name]") /* name属性を持つ要素 */
document.querySelectorAll("[name='area']") /* name属性が"area"の要素 */
document.querySelectorAll("[name^='area']") /* name属性が"area"から始まる要素 */
document.querySelectorAll("[name$='area']") /* name属性が"area"で終わる要素 */
document.querySelectorAll("[name*='area']") /* name属性が"area"を含む要素 */

CSSセレクター全体が" "で囲まれているため、その中では' 'を使います。逆にCSSセレクター全体が' 'で囲まれているなら、その中では" "を使います。

3番目の例は、いわゆる前方一致というもので、例えば name="areaEast" という属性を持つ要素があれば選択対象になります。同様に、 $= や *= を使えば後方一致や部分一致で選択できます。これらは意外と出番が多いです。

では、name属性が area で終わり japan で終わる要素(例えば area-east-japanやarea-west-japan)をまとめて捕まえるにはどうすれば良いでしょうか? 答えは、[name^='area'][name$='Japan'] です。並べて書けばOKです。

. クラスセレクター

属性の中でもクラス属性(class="top-menu"など)は頻繁に使われるため、[ ]ではなくて .(ピリオド)を使う書き方ができます。つなげて書くこともできます。

document.querySelector(".top-menu") /* top-menuというクラスを持つ要素 */
document.querySelector("div.topMenu") /* topMenuというクラスを持つdiv要素 */
document.querySelector("div.topMenu.news") /* topMenuとnewsのどちらも持つdiv要素 */

IDセレクターとは違い、多くの場合は複数の要素が返ってきます。最初の要素が取れればよいなら querySelector( ) でOKですが、全要素が必要ならquerySelectorAll( ) を使います。

要素型セレクター

HTMLタグを指定します。例えば div や table です。これだけだと絞り込みが緩すぎるのでクラスセレクターなどを併用することが多いです。

document.querySelectorAll("div") /* ページ内のすべてのdiv要素 */
document.querySelectorAll("div.topMenu") /* topMenuというクラスを持つdiv要素 */
document.querySelectorAll("div[name='menu']") /* name属性が"menu"のdiv要素 */

(空白) 子や孫やひ孫を探す

セレクターを空白を挟んで並べると、左側の要素の子孫(子、孫、ひ孫、…)になっている要素を選択できます。

/* 「topMenuクラスを持つdiv要素」の中にあるp要素 */
document.querySelectorAll("div.topMenu p")

上記の例では、
<div class="topMenu"><div><form><p>~~</p></form></div></div>
のように div の下に別の div と form が挟まっていても p 要素を選択できます。topMenu の div から見るとこの p はひ孫です。

> 直接の子要素を探す

上記のように空白でつなぐと、子だけでなく孫以降も取れてしまいます。直接の子だけを選択したいときは、空白の代わりに > を使います。

/* topMenuクラスのdiv要素の直下にあるdiv要素 */
document.querySelectorAll("div.topMenu > div")

の例では、
<div class="topMenu"><div class="articles"><div class="hotTopics"><p>~~</p></div></div></div>
に対して適用すると、articles クラスの div は取れますが、hotTopics クラスの div は取れません。直接の子だけを捕まえることができます。

, セレクターを複数並べる

複数のセレクターの検索結果をまとめたいときは、 , (カンマ)を挟んで並べます。

/* areaクラスのdiv要素とcategoryクラスのdiv要素をまとめて取る */
document.querySelectorAll("input.area, input.category")

以上!

お疲れ様でした

次回は練習問題をやりましょう。

今回のまとめ

HTMLの基礎と、重要なCSSセレクターを学習しました。この記事は今後も辞書的に使ってください。

プログラムを書いていると、すぐにこのページの内容では物足りなくなってくると思います。HTMLやCSSセレクター、そしてJavaScriptを初心者向けに説明してくれているwebページはたくさんありますので、ぜひ勉強して理解を深めてください!


次回はこちらです。

このシリーズのすべての記事は、こちらのマガジンにまとめています。

🐶スキしていただけると励みになります!

この記事が気に入ったらサポートをしてみませんか?