DOMParser を使う時の href
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ ドキュメント自体の場所情報がないので パス解決できないから空文字
◆ 属性を取り出して URL 関数を使って自分でパス解決済みの文字列を作る必要あり
◆ 属性を取り出して URL 関数を使って自分でパス解決済みの文字列を作る必要あり
DOMParser
xhr で HTML 持ってきてタイトルタグの中身を取り出したいとか xxxx の ID の要素の中身を取り出したいとかありますよね正規表現でパースするのはさすがにちょっとタイヘンです
DOM を扱えるんだから持ってきたデータも DOM として扱いたいッて思うはず
そんなときのために DOMParser というものがあります
var parser = new DOMParser()
var doc = parser.parseFromString(xhr.responseText, "text/html")
console.log(doc.querySelector("title").textContent)
var doc = parser.parseFromString(xhr.responseText, "text/html")
console.log(doc.querySelector("title").textContent)
これで取り出せます
DOM を構築するので文字列処理よりは時間がかかりますが 基本的に待ち時間を感じることはない程度です
parser インスタンスをわざわざ作る必要があるように思えないですがこういう仕様みたいです
いきなり DOMParser.parseFromString() でいいと思うんですけどね
href
parseFromString の返り値は document ですなので 普段の DOM と同じように getElementById などが使えます
そこで注意しないといけないのが a タグからリンクを取り出す時です
var parser = new DOMParser()
var doc = parser.parseFromString('<a href="/index.html">a</a>', "text/html")
doc.links[0].href
// ""
var doc = parser.parseFromString('<a href="/index.html">a</a>', "text/html")
doc.links[0].href
// ""
空文字になっています
原因は DOMParser で作った document 自体の location 情報がないからです
document の location プロパティを見てみると
doc.location
// null
document.location
// Location { }
作ったほうは null です// null
document.location
// Location { }
この JavaScript を動かしているページ自体の document の location には window.location が入っています
この location が href の基準になるものなので href プロパティは空文字になります
しかし location プロパティは読み取り専用なので変更できないです
対処方法
href プロパティは解決済みの最終的なリンク先が入っているものでこっちはベースとなる URL が不明なので使えませんですが 属性は取り出せます
なので自分でベース URL からの相対パス解決をしたパスに変換すればいいんです
var basepath = xhr.responseURL
console.log(Array.from(doc.links, e => new URL(e.getAttribute("href"), basepath).toString()))
console.log(Array.from(doc.links, e => new URL(e.getAttribute("href"), basepath).toString()))
こんな感じでできます
basepath は必要に応じて変えてください