例題
<ul>
<li>田中 あすか</li>
<li>中川 夏紀</li>
<li>黄前 久美子</li>
<li>久石 奏</li>
</ul>
この中から「久」を含む li 要素を取得する。jQuery を使えば
$('li:contains(久)');
と書ける。では jQuery を使わずに同様のことを実現するのはどうしたらいいだろうか
解答
Document.evaluate() と XPath の contain 関数を使う。
let xpath = "//li[contains(text(), '久')]";
let resultType = XPathResult.ORDERED_NODE_ITERATOR_TYPE;
document.evaluate(xpath, document, null, resultType, null);
この式は独自のイテレータを返す。値は例えば次のように取り出す。
let xpath = "//li[contains(text(), '久')]";
let resultType = XPathResult.ORDERED_NODE_ITERATOR_TYPE;
let results = document.evaluate(xpath, document, null, resultType, null);
while (true) {
let li = results.iterateNext();
if (!li) break;
console.log(li)
}
console
<li>黄前 久美子</li>
<li>久石 奏</li>
ちなみに、残念ながらこのイテレータは iterable プロトコル を満たしていないため、Array.from() や for...of は使えなかった。
要素を最初の 1 つだけ取得する場合は resultType
を変えて次のように書く。
let xpath = "//li[contains(text(), '久')]";
let resultType = XPathResult.FIRST_ORDERED_NODE_TYPE;
let li = document.evaluate(xpath, document, null, resultType, null).singleNodeValue;
console.log(li);
console
<li>黄前 久美子</li>
テキストを完全一致させる場合は XPath を次のように変える。
let xpath = "//li[text()='久石 奏']";
参考
- MDN web docs
- Document.evaluate()
- XSLT/XPath リファレンス
- Stack Overflow