ブックマークレットで始める業務改善⑩ JavaScriptで要素を絞り込もう
前回はこちら。
CSSセレクターでは手が届かない「かゆいところ」をカバーする、JavaScriptの関数などを解説します。これであなたもJavaScriptプログラマー!
前回までで、CSSセレクターについて詳しく学びました。しかし、CSSセレクターだけではうまく要素を捕まえられないことも多々あります。
そんなときは、JavaScriptの機能を使ってアプローチします。大きくは以下の2つの流れで、必要な要素を捕まえにいきます。
CSSセレクターで簡単に取れる要素を起点として、そこからの相対的な位置関係(親子関係など)を使って最終的に欲しい要素を捕まえる。
CSSセレクターで候補となる要素たちを探して、JavaScriptで必要な要素だけに絞り込む。
変数
まず、情報を格納しておく箱である「変数」について解説します。まずは例を見てみましょう。
下のプログラムは、message という変数に「こんにちは!」という文字列を格納(代入)した後で、message の中身を alert( )関数で表示しています。デベロッパーツールのコンソールにコピペして動かしてみてください。
const message = "こんにちは!";
alert(message);
message の前に付いている const は、「これ以降、 message に別の情報が代入される(上書きされる)ことはありません」という印です。後で上書きするときは const ではなく let を付けます。ほとんどのケースでは const で大丈夫でしょう。
変数名は何でもよいですが(数字から始まってはダメ、ハイフンは使えない、などの技術的なルールはあります)、名が体を表すような分かりやすい名前にしましょう。forEachの中などでは、e(element=要素 の略)のような非常に短い名前が使われることもあります(分かりやすさを損なわない限り)。
なんと、変数には文字列だけでなく、要素も入れることができます!😀
以下のブックマークレットを、このフォームで動かしてみてください。
javascript:(function()
const saisho_kingaku = 10000;
const minAmount = document.querySelector("#min-amount");
const maxAmount = document.querySelector("#max-amount");
minAmount.value = saisho_kingaku;
maxAmount.value = saisho_kingaku * 2;
})();
この例だとありがたみがありませんが、document.querySelector~~ と毎回長々と書かなくてもすぐにその要素にアクセスできて非常に便利です。
デベロッパーツールのコンソールでは、> のあとに変数名を入力してEnterキーを押せばその中身が表示されます。
以降、JavaScriptで要素を捕まえる方法を列挙します。サンプルプログラムは上記のフォームで動くように作ってあります。試してみてください。
※ サンプルですので、妙にまどろっこしい捕まえ方をしていたとしても気にしないでください。
ある要素を起点にして探す
ある要素を起点にした querySelector( ) と querySelectorAll( )
これまで、querySelector( ) や querySelectorAll( ) は、document につなげる形で使ってきました。document はHTML文書全体を示しています。
実はこれらの関数は、個々の要素からつなげることもできます。そうすると、その要素を起点として、その子孫要素の中で検索をかけられます!
const menu = document.querySelector("#search_form");
menu.querySelector("input[type='text']").value = 20000;
上記の例では、search_form というIDを持つ要素を menu という変数に代入して、menu を起点としてその中で「customerクラスを持つinput要素」を探して、そこに会社名を入れています。
CSSセレクターで一発で取るのが難しいときは、このように段階を分けて捕まえに行くことができます。
parentNode 親を捕まえる
ある要素の親を捕まえるには parentNode を使います。
const e = document.querySelector("#min-amount").parentNode;
CSSセレクターで簡単に取れる要素から見て「兄弟の要素」が欲しいときは、parentNode で親要素を取り、そこから querySelector( ) で最終的に欲しい要素を取りに行く、といったことができます。
closest( ) CSSセレクターで先祖を捕まえる
この関数は、指定されたCSSセレクターにマッチするものが見つかるまで、親をさかのぼって探しに行ってくれます。(起点となる要素がマッチするときはその要素が取れます。)
下記のプログラムは、「min-amount というIDを持つ要素」を子孫に持つ、「formBoxというクラスを持つdiv要素」を捕まえています。
const e = document.querySelector("#min-amount").closest('div.formBox');
CSSセレクターで簡単に取れる要素が階層の深いところに埋まっているときなどに活用できます。
activeElement 選択されている要素を捕まえる
これはちょっと変わり種で、今選択されている(フォーカスが当たっている)要素を捕まえることができます。
const e = document.activeElement;
例えばテキスト入力欄に何かをコピペして、それを適切な形に加工する(スペースをカンマで置き換えるなど)といったときに便利です。
要素を絞り込む
querySelectorAll( ) はCSSセレクターに当てはまる要素がすべて取れますが、実際に操作するのはその中のひとつだけ、といったことも多いです。そんなときに絞り込みを行う方法を解説します。
[ ] 何番目かで指定する
querySelectorAll( )が返してきた複数の要素の中で、必要なものの位置(順番)が分かっているときは、[ ]の中にその番号を入れればその要素にアクセスできます。
下記の例では、querySelectorAll( ) の結果の中で2番目の要素を捕まえています。[ ]に入れる数字は0はじまりなので、[1]とすると2番目になります。ややこしい!
const e = document.querySelectorAll("input[type='text']")[1];
変数に[ ]を付けることもできます。そのまま.valueなどを付けることもできます。
const elements = document.querySelectorAll("input[type='text']");
elements[1].value = 30000;
innerText コンテンツを得る(trim( )と併用)
要素のコンテンツになっている文字列(開始タグと終了タグの間にある文字列)を取得する関数です。子要素のコンテンツも含みます。
const e = document.querySelector("h2.title");
alert(e.innerText);
HTML文書はその中に、最終的には表示されない空白やタブ記号などが入っていることがあります。innerText はそれも含めて取ってきてしまいます。trim( ) を使えば、文字列の前後にくっついている空白やタブ記号などを削除できて便利です。
const str = " Hello, world! ";
str.trim();
innerText.trim( ) のように合わせて使うと効果的です。
if文 条件に当てはまるときだけ処理する
基本的な条件分岐を行うための仕組みです。基本的な書き方は以下の通りです。
if (条件) {
条件が成立したときに行う処理
}
以下のブックマークレットは、aタグの要素をすべて取ってきた上で、その中身をinnerTextでひとつずつ見ていき、"検索" と書かれた要素が見つかればクリックする、という処理を行います。二つのものが同じかどうかは、 === で判定できます。逆に、違うかどうかは !== で判定します。
javascript:(function(){
document.querySelectorAll("a").forEach(function(e) {
if (e.innerText.trim() === '検索') {
e.click();
}
});
})();
if文は、else if や else を使えば条件分岐を細かく分けることができます。調べてみてください。
filter( ) 条件に当てはまる要素だけに絞り込む
if文の代わりに filter( ) を使うと、1行で書けてスッキリすることがあります。ただし filter( ) を使うためには、querySelectorAll( ) を Array.from( ) で囲む必要があります。
以下のブックマークレットは、上のif文を使ったものと全く同じ動作をします。
javascript:(function(){
Array.from(document.querySelectorAll('a')).filter(e => e.innerText.trim() === '検索')[0].click();
})();
length 要素の数を数える
querySelectorAll( ) や filter( ) で見つかった要素の個数は length で分かります。以下のように書けば、要素が見つかったときだけ処理を行うことができます。
const elements = document.querySelectorAll("input[type='text']");
if (elements.length !== 0) {
alert("要素が" + elements.length + "個見つかりました!");
}
補足
/* */ コメントを書く
JavaScriptのプログラムには、/* */ で囲むとコメントを入れられます。実行時には無視され、処理に影響しません。プログラムを見ただけでは分かりにくいところなどにコメントを書いておきましょう。
※ // を使ったコメントは、ブックマークレットの中では使えません。
ネットでの情報の調べ方
例えば、「捕まえた要素が特定のクラスを持っているかどうか判定する方法」をGoogleで調べるには以下のように入力します。
JavaScript 要素 クラスを持つか
最近だと、ChatGPTなどで聞くのも便利です。試しにやってみたら以下のように親切に教えてくれました。すごいですね😮
今回のまとめ
JavaScriptで要素を捕まえる方法を学習しました。より高度な内容は、自分でネットや書籍で調べてみてください。
次回はJavaScriptで要素を操作する方法を学習します。
次回はこちらです。
このシリーズのすべての記事は、こちらのマガジンにまとめています。
🐶スキしていただけると励みになります!