順番通りにIFrameを読み込むJavaScriptライブラリ「IFrameNeatLoader」

hosikiti2013-09-05


久しぶりにコンパクトなJavaScriptのライブラリを書いた。
IFrameの中身を指定した順番で読み込ませたい!というニッチな要件に対応する「IFrameNeatLoader.js」を公開する。

機能

  1. 読み込み順をIFrameの属性に数値で定義できる
  2. フレームのロード完了まで、次のフレームは読み込まれない
  3. IEChromeで動作確認済
  4. メモリリーク対策も考慮済

必要なライブラリ

  1. jQueryの1.7以上必要

使い方

  1. jQueryを読み込む
  2. IFrameNeatLoader.jsを読み込む
  3. 順番を制御したいIFrameのdata-loadOrder属性に読み込む順番を書く(1,2,3...)
  4. 同様に、IFrameのdata-src属性に読み込ませる対象URLを書く
  5. IFrameの定義後に IFrameNeatLoader(); で初期化。

これだけだ。
ソースを見てみよう。まずはライブラリの「IFrameNeatLoader.js」

var IFrameNeatLoader = function(attrLoadOrder, attrSrc){
    var ATTR_LOAD_ORDER = attrLoadOrder || "data-loadOrder";
    var ATTR_SRC = attrSrc || "data-src";

    // get iframes
    var iframes = document.getElementsByTagName('iframe');
    if( iframes.length == 0 ){
        return;
    }

    // sort by load order attribute
    var iframeArray = [];
    for( var i= 0, len= iframes.length; i<len; i++){
        iframeArray.push(iframes[i]);
    }
    Array.prototype.sort.call(iframeArray,function(a,b){
        var x = a.getAttribute(ATTR_LOAD_ORDER) || 0;
        var y = b.getAttribute(ATTR_LOAD_ORDER) || 0;
        return x-y;
    });

    // load iframes by order specified
    var isIE = document.all != undefined;
    (function(startIndex){
        var self = arguments.callee;
        for( var i= startIndex, len= iframeArray.length; i<len; i++){
            var iframe = iframeArray[i];
            if( !iframe.getAttribute(ATTR_LOAD_ORDER) || !iframe.getAttribute(ATTR_SRC) ){
                continue;
            }
            if( isIE ){
                $(iframe).one("readystatechange", function(){
                    if( this.readyState == "complete" ){
                        self(++i);
                    } else {
                        $(this).one("readystatechange", arguments.callee);
                    }
                });
            } else {
                $(iframe).one("load", function(){
                    self(++i);
                });
            }
            iframe.src = iframe.getAttribute(ATTR_SRC);
            iframe = null;
            break;
        }
    })(0);
};

次に、上のライブラリを使うためのテスト用のHTML。
「test.html」とでもしておく。

<!DOCTYPE html>
<html lang="ja">
<head>
     <meta charset="UTF-8">
     <title></title>
</head>
<body>
<iframe src="about:blank" data-loadOrder="3" data-src="//www.yahoo.co.jp/" frameborder="0" width="200" height="160"></iframe>
<iframe src="about:blank" data-loadOrder="2" data-src="http://semooh.jp/jquery/api/events/" frameborder="0" width="200" height="160"></iframe>
<iframe src="about:blank" data-loadOrder="1" data-src="http://www.infoseek.co.jp/" frameborder="0" width="200" height="160"></iframe>
<iframe src="http://www.goo.ne.jp/" frameborder="0" width="200" height="160"></iframe>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="js/IFrameNeatLoader.js"></script>
<script type="text/javascript">
     IFrameNeatLoader();
</script>
</body>
</html>

上記2ファイルを

test.html

--- js

|--- IFrameNeatLoader.js

てな感じで配置してtest.htmlをブラウザで開いてみると、右から「goo」「infoseek」「jQuery APIリファレンス」「Yahoo」と読み込まれるのがわかるはずだ。一番右のgooのフレームは通常のIFrameなので即座に読み込まれ、その次は data-loadOrderが一番小さい数字のものから、つまり、このtest.htmlでは右から二番目のinfoseekのフレーム(data-loadOrder=1)から順に読み込まれていく。

ちなみに、この読み込み順と読込対象URLを指定する属性は変更可能だ。IFrameNeatLoader(); の初期化のときに、

IFrameNeatLoader(読み込み順属性, 読込対象URL属性)

と書く。例えば、description属性に読み込み順、title属性にURLを指定する場合は

IFrameNeatLoader("description","title");

と書けば良い。