DevTools の検索にハマった話
Chrome の DevTools の Elements パネル で DOM を検索していて、
<link rel="canonical" href="https://domain.jp/home/">
のようにHTMLの属性ごと検索したいがヒットしない問題に当たりました。
経緯
メタな話をすると、canonical使用箇所は一箇所しか無いのが常ですが、
毎回canonicalで打ってhrefの値を見に行くという手間を限りなく省きたく、
canonicalタグのhrefの値を取得したいだけだが、
hrefの値は他でも使用しているため、値だけを検索しても他の値がノイズとして引っかかる。
という事象により、ええいhtmlタグを検索してしまえ(ダブりがないとわかっている前提)という経緯でした。
このお話は、「いかに手間を省いて、狙った要素だけを検索でヒットさせるか」という観点で読んでいただければと思います。
検証:検索でヒットする、しないワード
まず、以下の内どこからヒットしなくなるかを探した結果は下記。
<link rel="canonical" href="https://domain.jp/home/">
結論: =をつけた時点でヒットしなくなることがわかりました。
⭕️:<link
⭕️: canonical
❌️: <link rel
❌️: rel="canonical"
❌️: href="https://domain.jp/home/"
❌️: rel=
上記からhtmlタグは検索されない?と思いますが、
下記のようなシンプルなタグは認識されます。
⭕️: <title>
devtoolsが検索で処理している形式
ここで検索欄にあるPlaceholderのテキストを確認します。
「文字列、セレクタ、またはXPathで検索」とあることから、
- 文字列
- CSSセレクタ
- XPath
を認識をしていることがわかります。
ここで挙動をまとめると
上記の結果から、
- canonical のような「ただの単語」は文字列検索としてヒットする
- 一方で rel="canonical" のように = が入る書き方をすると、DevTools が CSS セレクタとして解釈しようとしてコケてしまう
-
<title>のようなシンプルなタグ文字列は、DOM 全体を HTML 文字列として検索した結果ヒットしている
という挙動なんだろう、というところまで見えてきました。
文字列の挙動
「文字列」と聞くと、まずは
<p>テキスト</p>
のテキスト部分(テキストノード)を想像するとイメージしやすいです。
また、下記のような属性値(/top, handleClick)も文字列としてヒットします。
<a href="/top" onClick="handleClick">TOP</a>
では<title>がヒットしていたのはなぜなのか。
これは検索が DOM 全体を「HTMLの文字列」としても見ているためでした。
<title>サイト名</title>
はサイト名、<titile>どちらも、「その文字列そのもの」として文字列検索の対象になっているようです。
CSSセレクタの挙動
まず、= が使えなかった問題は、この CSS セレクタモードで弾かれたからでした。
rel="canonical"のような書き方はCSS セレクタとしては不正で、
本来は [rel="canonical"] のように角カッコで囲む必要があります。
今回 DevTools は、rel="canonical" を「CSS セレクタとして解釈しようとして失敗した状態」
で止まってしまうため、単なる文字列検索にもフォールバックせず、
結果として「= を入れた途端にヒットしない」という挙動になっていました。
CSS セレクタとして書くなら、例えば次のようになります。
a[href="/login"] /* /login に飛ぶリンク */
a[href^="/login/"] /* /login/ から始まるリンク */
a[href*="login"] /* login を含むリンク */
input[type="checkbox"] /* チェックボックスだけ */
このような CSS セレクタとして有効な形 にすると、DevTools からも正しく検索できます。
今回のやりたいことに当てはめると下記のように書けます。
link[rel="canonical"][href="https://domain.jp/home/"]
XPathの挙動
XML Path Language (XPath(エックスパス)) は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文である。
XPathは、XML文書中から必要な要素群(サブセット)を取り出す、などといった用途に使うもの
wikipedia: XML_Path_Language
恥ずかしながらいままでXPathと向き合うことがなかったのですが、
今回調べてみると意外と使いやすいことがわかりました。
要素検索
//div
//h3
//a
と打つとdiv,h3,aタグがそれぞれヒットします。
/を2個打つだけで良いのが楽です。
今回やりたいことをXPathで表現すると、
//link[@href="https://domain.jp/home/"]
でヒットします。
要素を追加するなら、[]をあとに付け足せばよいです。(または中でandをつなぐ)
//link[@rel="canonical"][@href="https://domain.jp/home/"]
//link[@rel="canonical"][contains(@href, "home/")]
//link[@rel="canonical" and contains(@href, "home/")]
このように、CSS セレクタと同じ発想で「タグ+属性」の組み合わせで絞り込めます。
まとめ
以上のことから、DevTools の検索で = を使いたい場合は、
最初から CSS セレクタか XPath の文法で書く必要があるということがわかります。
XPath の要素検索は、タグの個数を数えたり構造をざっと確認したりするのにはちょうどよいと感じました。
ただ、毎回ここまでセレクタを組むかというと、正直そこまで頻度は高くないかもしれません。
一方で、テストや調査のときにコピペするだけで
「想定どおりの canonical / href になっているか」だけ確認したい
といったケースでは、役に立つ場面もありそうだと感じています。
以上です。
DevTools の検索の挙動にハマった一例として、
読んでいただいた方の調査時間が数分でも短くなれば幸いです。
