iframe と base の組み合わせが便利だった
◆ base タグで相対パスの基準になるパスを設定できる
◆ iframe と組み合わせたらここのブロックだけ 相対パスの基準を変えたいってことができる
◆ iframe と組み合わせたらここのブロックだけ 相対パスの基準を変えたいってことができる
前にこんな記事を書きました
説明がしづらいので 分かる人多いですし特に問題ないのでマークダウンってことにします
次に HTML でのビュワーを作ります
ビュワーでは 適当な変換するライブラリを使って HTML に変換して ビュワーのトップページに innerHTML を埋め込む感じで表示します
こうすると a タグや img タグなどの URL を指定するところに相対パスを書いていた場合 .md ファイルからの相対パスとして書かれているのに 実際はビュワーのトップページからのパスとしてブラウザが処理してしまいます
なので 相対パスを使っていると URL 部分が全部ちゃんと動きません
前回は innerHTML を置き換えて DOM の構築した直後に querySelector で URL あるタグを取り出してプロパティの書き換えで対応していました
画像の場合でもロードする前なので 特に問題はなかったのですが なんかいい方法じゃないなぁと思ってました
img タグだと src 属性で a タグだと href 属性で と自分で全部指定する必要があります
マークダウンだとなさそうですが video や audio などのタグだって URL を書くことは可能です
機能は 相対パスの基準のパスを設定します
つまりこのタグで .md のパスを書いておけば 勝手に a タグも img タグもなってほしいパスになってるんです
こんな便利タグがあったなんて!!
ですが 問題点もあります
この div 以下だけ相対パス変える っていうのはできないです
全体が変わります
一応 base タグが作られる前に読み込まれたタグは本来の 表示している HTML からの相対パスで解決されます
どうにかできないかなー と考えていたら iframe が思い浮かびました
iframe は src 指定していないと about:blank になっていて window.open で about:blank を開いた時と同じで JavaScript で操作可能です
ビュワーの中でマークダウンのテキストを表示する部分を iframe にしておいて マークダウンを開いた時に base タグの href 属性を変更してから innerHTML を設定します
init は最初に実行しておきます
base タグより前にマークダウン用の CSS を読み込んでおきます
loadDocでマークダウンの読み込みです
convertDoc はマークダウンから HTML の変換です
相対パスの基準を変えたいときは たいていそこだけ別のまとまりになるはずですから 別フレームになっているせいで CSS や JavaScript が別になってしまうというのもプラスになることが多いんじゃないかと思います
説明がしづらいので 分かる人多いですし特に問題ないのでマークダウンってことにします
問題点
マークダウンをエディタで書いてプレビューすると画像ファイルやリンクが相対パスだったら .md ファイルからの相対パスになると思います次に HTML でのビュワーを作ります
ビュワーでは 適当な変換するライブラリを使って HTML に変換して ビュワーのトップページに innerHTML を埋め込む感じで表示します
こうすると a タグや img タグなどの URL を指定するところに相対パスを書いていた場合 .md ファイルからの相対パスとして書かれているのに 実際はビュワーのトップページからのパスとしてブラウザが処理してしまいます
なので 相対パスを使っていると URL 部分が全部ちゃんと動きません
前回は innerHTML を置き換えて DOM の構築した直後に querySelector で URL あるタグを取り出してプロパティの書き換えで対応していました
画像の場合でもロードする前なので 特に問題はなかったのですが なんかいい方法じゃないなぁと思ってました
img タグだと src 属性で a タグだと href 属性で と自分で全部指定する必要があります
マークダウンだとなさそうですが video や audio などのタグだって URL を書くことは可能です
base タグ
あまり知られていないタグだと思います (というか私も今回たまたま知って「コレ使える!!」と思ったわけですけど)機能は 相対パスの基準のパスを設定します
つまりこのタグで .md のパスを書いておけば 勝手に a タグも img タグもなってほしいパスになってるんです
こんな便利タグがあったなんて!!
ですが 問題点もあります
この div 以下だけ相対パス変える っていうのはできないです
全体が変わります
一応 base タグが作られる前に読み込まれたタグは本来の 表示している HTML からの相対パスで解決されます
iframe と組み合わせる
全体の基準の URL が変わると ビュワー全体の制御用の JavaScript や 全体のデザインの CSS や画像のパスがビュワーのトップページからの相対パスじゃなくなってしまい困りますどうにかできないかなー と考えていたら iframe が思い浮かびました
iframe は src 指定していないと about:blank になっていて window.open で about:blank を開いた時と同じで JavaScript で操作可能です
ビュワーの中でマークダウンのテキストを表示する部分を iframe にしておいて マークダウンを開いた時に base タグの href 属性を変更してから innerHTML を設定します
var framedoc = frames[0]
function init(){
framedoc.head.innerHTML = `
<link rel="stylesheet" href="style.css">
<base id="base" href="/">
`
}
function loadDoc(docpath){
var base = new URL(docpath, location.href)
framedoc.querySelector("base").href = base
fetch(docpath).then(e => e.text()).then(doc => {
var html = convertDoc(doc)
framedoc.body.innerHTML = html
})
}
function init(){
framedoc.head.innerHTML = `
<link rel="stylesheet" href="style.css">
<base id="base" href="/">
`
}
function loadDoc(docpath){
var base = new URL(docpath, location.href)
framedoc.querySelector("base").href = base
fetch(docpath).then(e => e.text()).then(doc => {
var html = convertDoc(doc)
framedoc.body.innerHTML = html
})
}
init は最初に実行しておきます
base タグより前にマークダウン用の CSS を読み込んでおきます
loadDocでマークダウンの読み込みです
convertDoc はマークダウンから HTML の変換です
まとめ
base タグを iframe と組み合わせると ここのまとまりだけ相対パスの基準を変えたいってときにはとても便利です相対パスの基準を変えたいときは たいていそこだけ別のまとまりになるはずですから 別フレームになっているせいで CSS や JavaScript が別になってしまうというのもプラスになることが多いんじゃないかと思います