michimani.net

【続】動的に埋め込んだiframeの高さを取得する

2018-11-29

前にも同じ内容で書いた んですが、スマートな方法ではなかったので考え直しました。
前回は jQuery を使っていましたが、今回は使わない方法で実装してます。

前提

前回と同様に、クリックした要素のリンク先を iframe で挿入して、挿入したページの高さを取得する、ということをやります。

検証用の構造は下記のような構成になっています。

.
├── hogehoge-1
│   └── index.html
├── hogehoge-2
│   └── index.html
├── hogehoge-3
│   └── index.html
├── index.html
└── test.js

各ファイルの内容は次の通り。

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>GET IFLAME HEIGHT</title>
</head>
<body>
    <div id="content-area"></div>

    <ul>
        <li><a class="iframe-btn" href="./hogehoge-1/index.html">hogehoge 1</a></li>
        <li><a class="iframe-btn" href="./hogehoge-2/index.html">hogehoge 2</a></li>
        <li><a class="iframe-btn" href="./hogehoge-3/index.html">hogehoge 3</a></li>
    </ul>

    <script src="./test.js"></script>
</body>
</html>

test.js

const btnElems = document.querySelectorAll('.iframe-btn');
for (let i = 0; i < btnElems.length; i++) {
    btnElems[i].addEventListener('click', (event) => {
        event.preventDefault();
        insertIframe(event);
    });
}

function insertIframe(btnElem) {
    const iframeArea = document.getElementById('content-area');
    iframeArea.innerHTML = '';
    let insert = new Promise((resolve) => {
        let iframe = `<iframe frameborder="no" src="${btnElem.target.href}"></iframe>`;

        console.log('insert iframe.');
        iframeArea.innerHTML = iframe;
    });

    insert.then(getIframeHeight());
}

function getIframeHeight() {
    let iframe = document.querySelector('#content-area iframe');
    if (iframe != null) {
        iframe.contentWindow.addEventListener('load', (event) => {
            console.log(document.querySelector('#content-area iframe').contentWindow.document.body.scrollHeight);
        });
    } else {
        console.log('iframe does not exists.');
    }
}

hogehoge-*/index.html

hogehoge-1 は高さ 100px 、hogehoge-2 は高さ 200px 、 hogehoge-3 は高さ 300px になってます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>GET IFLAME HEIGHT</title>
</head>
<body>
    <div style="height: 100px;">
        <h1>hogehoge-1 100px</h1>
    </div>
</body>
</html>

前回から変わったところ

まず、冒頭にも書きましたが jQuery を使わないようにしました。最近はできるだけ生の JavaScript の記述で実装するようにしています。
iframe 内のページの高さを取得するためには、当たり前ですが iframe の描画が終わっている必要があります。
前回は setTimeout を使って 200 ミリ秒待つ みたいなことをしてましたが、完全ではありません。

今回は、iframe の挿入と高さの取得の処理順を Promise を使って制御するようにしました。
また、 iframe 内のページの高さ取得自体は、そのページが load されたタイミングで取得するようにしました。

結果

上記の構成で、ルートの index.html にて、 hogehoge-1hogehoge-2hogehoge-3 の順にボタンをクリックすると、コンソールには下記のように出力されます。

insert iframe.          test.js:15
100                     test.js:26
insert iframe.          test.js:15
200                     test.js:26
insert iframe.          test.js:15
300                     test.js:26

動的に埋め込んだ iframe の高さを取得できています。
前回よりはスマートになったと思います。


comments powered by Disqus