Javascriptで外部htmlを読み込む方法のサンプル XHR / fetch id指定 / class指定 load後のhtmlにcssを適用する方法。

目次

目的

外部のhtmlファイルを読み込む方法は、iframeやphpなどもありますが、ここではJS(Jqueryではない)で行っています。
JSで行う理由もいろいろ有るかと思いますが、
  • iframeだとCSSを適用しにくくレスポンシブに対応しづらい
  • phpを使えない環境
  • 読み込んだあとのhtmlにJSを適用したい
などの理由があったのでまとめました。

JS 外部HTML読み込み 5パターンのデモ

1 XHRでロードする

<div id="loadArea-1" class="loadTo"></div>

<script>
    // Pure JS Load XHR 【 --要変更--  変数:7箇所  ID:1箇所 元URL:1箇所 】
    var myXml = new XMLHttpRequest();
    myXml.onreadystatechange = function() {
        if ((myXml.readyState === 4) && (myXml.status === 200)) {
            document.getElementById("loadArea-1").innerHTML = myXml.responseText; // 挿入先ID
            // ロード後の処理を記述
        }
    }
    myXml.open("GET", "https://eating2003.com/demo/load-source.html", true);  // 元URL 
    myXml.send(null);
</script>
XHRを使ったロード。ここでは元htmlを丸ごと指定したID(#load-Area-1)の中にロード。
ロードしたhtmlに対してJSを適用する場合は、「ロード後の処理を記述」部分に書くことで適用される。
メリット 古いブラウザでも動作する。
デメリット 変数の指定箇所が多い。

2 fetchでloadする(htmlまるごと)

<div id="loadArea-2" class="loadTo"></div>

<script>
    window.addEventListener('DOMContentLoaded', function(){
        fetch('https://eating2003.com/demo/load-source.html') //ロード元URL
        .then(data => data.text())
        .then(html => document.getElementById('loadArea-2').innerHTML = html) //ロード先ID指定
        .then(() => {
                //ロード後の処理を記述                 
            });
    });
</script>
fetchでhtmlを丸ごとロードしてくる。
DOMContentLoadedのタイミングでロード開始し、#loadArea-2の中に、元htmlを丸ごと挿入する。
ロードしたhtmlに対してJSを適用する場合は、「ロード後の処理を記述」部分に書くことで適用される。
メリット XHRよりも記述が少ない。
デメリット IEなど古いブラウザで動かない。

3 fetchで、指定IDをloadする

<div id="loadArea-3" class="loadTo"></div>

<script>
    window.addEventListener('DOMContentLoaded', function(){
        fetch('https://eating2003.com/demo/load-source.html') //【ロード元URL】
            .then(response => response.text()) .then(data => { 
                const parser = new DOMParser();
                const html = parser.parseFromString(data, "text/html");
                const boxs = html.querySelectorAll('#Area2');//【ロード元ID】
                const file_area = document.getElementById('loadArea-3');//【ロード先ID】
                for(var box of boxs) {file_area.appendChild(box);}
        }); 
    });
</script>
fetchで元htmlの中のIDを指定して、指定したIDの中にロードする。
※下の4番目の方法と共通にしたため、querySelectorAll、forに無駄があります。
※元htmlを全部取得ではないため、デモではCSSが効いているように見えますが、これは1番目、2番目のまるごとロードしたときのCSSが効いてしまっているだけです。部分的にロードし、CSSを適用させる場合には、ロード先のHTMLに記述します。
また、その場合、ロード先の指定HTMLよりも前にCSSを記述しておいたほうがCLSなどが発生しにくいです。

4 fetchで、指定クラス全部をloadする (li.areaBoxをすべて ul無し)

<div id="loadArea-4" class="loadTo"></div>

<script>
    window.addEventListener('DOMContentLoaded', function(){
        fetch('https://eating2003.com/demo/load-source.html') //【URL】
            .then(response => response.text()) .then(data => { 
                const parser = new DOMParser();
                const html = parser.parseFromString(data, "text/html");
                const boxs = html.querySelectorAll('li.areaBox');//【ロード元クラス】
                const file_area = document.getElementById('loadArea-4');//【ロード先ID】
                for(var box of boxs) {file_area.appendChild(box);}
        }); 
    });
</script>
ロード元のクラスをquerySelectorAllで指定し、forですべてをロード先IDの中にロードする。
デモでは、li.areaBoxすべてを取得し、ロード先にはulが無い状態になっています。
CSSも3番目の場合と同様に適用されていません。

5 fetchで、指定クラス全部をloadしてCSSを適用(li.areaBoxをすべて ulの中にload)

<style>
    ul#loadArea-5 {
        display: flex;
        width: 80%;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
    }
    ul#loadArea-5 li {
        display: inline-block;
        width: 30%;
        height: auto;
        margin: 0 1% 10px 0;
        background-color: #b4eafc;
        padding: 10px;
    }
    ul#loadArea-5 li div {
        display: inline-block;
        width: 100%;
        height: auto;
        background-color: #65c8e6;
        text-align: center;
    }
</style>

<div class="loadTo">
    <ul id="loadArea-5"></ul>
</div>

<script>
    window.addEventListener('DOMContentLoaded', function(){
        fetch('https://eating2003.com/demo/load-source.html') //【URL】
            .then(response => response.text()) .then(data => { 
                const parser = new DOMParser();
                const html = parser.parseFromString(data, "text/html");
                const boxs = html.querySelectorAll('li.areaBox');//【ロード元クラス】
                const file_area = document.getElementById('loadArea-5');//【ロード先ID】
                for(var box of boxs) {file_area.appendChild(box);}
        }); 
    });
</script>
ロード先のulにIDを振って、そこにロード元のliをすべてロードしてくる。
ロード後にCSSを効かせるため、ulよりも前に、CSSを記述。
※ロード元のliに適用されているCSSは、htmlのみ引っ張られてしまうため効かなくなり、ロード先で新しいCSSが適用されます。これは元のページの内容を違った形で表示したいときに便利です。
もくじ
TOP
目次
閉じる