INWAN'S LABO

私はjavascriptでブラウザで遊べるミニゲームを作っています。

そのゲームをより多くの人に遊んでもらいたいのでブログパーツ的に簡単に埋め込めるような方法を考えてみました。

 

もともと埋め込み自体はiframeでできますがiframeだとコードにいろんなプロパティがあって詳しくない人には難しいし面倒くさいです。

なのでプロパティをサイズだけにしてわかりやすい形にしてみました。

 

シンプルな埋め込みコード

で、さっそく埋め込みコードなんですが、data属性を使って幅と高さを指定できるようにします。

この値をjavascriptで取得して指定のクラス名(この例ではembed-test)の所にiframeを作るようにします。

<div class="embed_test" data-width="300" data-height="200"></div> 
<script src="https://inwans.com/embed-game.js"></script>

御覧の通り直接iframeで書くよりかはだいぶわかりやすいスッキリしていて詳しくない人でも幅と高さの変更はできると思います。

 

javascriptのプログラム

次にjavascriptファイル(今回の例ではembed-game.js)を作ります。

var loadGame = function(){
    const elms = document.getElementsByClassName('embed-test');
    for(let i = 0; i < elms.length; i++){
        const elm = elms[i];
        if(elm.hasChildNodes()){//子要素がある場合
            if(elm.firstChild.tagName == 'IFRAME'){
                return;
            }
            while(elm.firstChild){
                elm.removeChild(elm.firstChild);
            }
        }
        const w = elm.getAttribute('data-width') ? elm.getAttribute('data-width') : '300';
        const h = elm.getAttribute('data-height') ? elm.getAttribute('data-height') : '450';
        
        const iframe = document.createElement('iframe');
        iframe.scrolling = 'no';
        iframe.frameBorder = 0;
        iframe.marginWidth = 0; 
        iframe.marginHeight = 0;
        iframe.width = w + 'px'; 
        iframe.height = h + 'px';
        iframe.src = '埋め込みたいページのurl';

        elm.appendChild(iframe);
    }
}
//サイトの読み込みが完了してからゲームを読みこむ
window.addEventListener("DOMContentLoaded", loadGame, false);

基本的にgetAttribute()でdata属性の値を取得してそれでiframeのサイズを指定するだけです。

 

最終的に上のような感じにできたんですが、出来上がるまでにいくつか困ったことがありました。

 

複数埋め込まれた場合の問題

ユーザーが埋め込む場合、1ページに一つとは限らないわけです。いくつかの場所に埋め込むかもしれない。そうなった場合にどうするのか?

 

なのでとりあえず要素はidではなくclassで作ってfor文である数だけiframeを作るようにしました。

 

ただ、これは読みこまれるjavascriptファイルがが1回なら問題ないんですが複数埋め込まれた場合、javascriptファイルも当然複数あると考えるのが普通。

となると今度はaddEventListenerがいくつも実行されてしまうという問題があるわけです。

 

とはいえすでに一度javascriptファイルを読んでるかどうかの判定はできないので、すでに子要素が作られていたら抜けるようにしたんですよ(子要素があるってことは2回目以降ってことだもんね)。

そしたらですね、はてなブログでうまく動かなくて。。

どうやらはてなブログではdivタグ内が空だったら勝手に何か入れられるようになってるぽいです。

 

仕方ないので一度removeChildで空にして作るってしたんですが、そうなると作って消して作って消してみたいな無駄なことを繰り返す羽目になってしまうので、子要素があった場合にそれがiframeかどうかチェックするようにしてiframeがあったらreturnで抜けるようにしました。

 

おしまい

JavaScriptでミニゲームや簡単なwebアプリなどを作ってみんなに使ってもらいたいときに試してみてください。