趣味的なIT・ネットの話題

ハイブリッドアプリでシステム開発:JSでボタンへのイベント登録はloadの後じゃ無いとだめ

最近流行のハイブリッドアプリの開発に挑戦してみようと思い、実質二択であるmonacaとionicを試してみることに強いました。まずはmonacaから。

HTML5+JavaScriptを標榜するだけあって、開発自体はHTML5+JavaScriptそのまんまな感じですね。HTMLで書いてJSのイベントドリブンで記述していきます。

ここでハマったのが、HTML要素にイベントを登録するには、ページの読み込み、または少なくともDOMツリーの構築が完了してからで無いといけないということ。以前にNodeでシステムを作っていたときには意識していたはずなんですが、すっかり忘れていました。というかこのあたりは公式チュートリアルとか公式本で言及しておいて欲しいところです。甘い?

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
    <script src="components/loader.js"></script>
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="css/style.css">
    <script type="text/javascript" charset="utf-8" src="index/main.js"></script>
    <script>
        ons.bootstrap();
        var datenow = new Date();
        console.log(datenow.toString());
    </script>
</head>
<body>
    <ons-navigator var="myNavigator" page="page1.html">
    </ons-navigator> 
</body>

</html>

内容は公式のサンプルのOnsen UIの最小限のテンプレに記述を加えたものです。

<script>
    $("ons-button#page1button"),on("click",function(e){
       console.log("test script on page1.html ");    
})
</script>

<ons-page id="page1">
    <ons-toolbar>
        <div class="center">Navigator</div>
    </ons-toolbar>
    <div style="text-align: center">
        <br>
        <ons-button id="page1button">
            test button 1
        </ons-button>
        
        <ons-button id="page2button"
            onclick="onClickTest()">
            test button 2
        </ons-button>

    </div>

</ons-page>

windowのloadイベントが発火した後に実行したaddEventLinsterとかJQueryのonは有効なようで、関数が登録されちゃんと実行されます。一方スクリプト読み込み時に実行されるものは登録されませんでした。

/*
//これは動作しない
document.getElementById("page1button").addEventListener("click", function(e){
    console.log("test log addeventlister non jquery 1");
});

//これも動作しない
document.addEventListener("click", function(e){
   if(e.target.id ==="page1button"){
       console.log("test log addeventlister non jquery 2");
   }
});

//これも動作しない
$("ons-button#page1button"),on("click",function(e){
       console.log("test log addeventlister jquery");    
})

//これらを記載してコメントアウトしない状態だとloadイベントで追加する方も実行されなくなる
*/

    
//これはok しかしhtml側に関数名を都度記述しないといけない
function onClickTest(){
    console.log("test onclick element");
}


//windowのloadイベントはページ要素の描画完了後
//参考 http://himco.jp/monaca/?p=306
window.addEventListener("load", onLoad, false);
function onLoad(){
    //これは動作した
    document.getElementById("page1button").addEventListener("click", function(e){
        console.log("test function added after load by addeventlister");
    });
    //これは動作した
    $("#page1button").on("click",function(e){
       console.log("test function added after load by jquery");    
    })
};

HTML側のonclickで登録した関数については実行されるのですが、これだと関数名を記述しないといけなくなり、JS側のロジックの一部をHTML側に持ち込むことになり美しくないと思います。動的にHTMLを生成してJSの関数を実行する際にも問題が出そうなので、できるだけloadをきっかけに登録する方法で行くことにします。


Facebooktwitterpinterestlinkedinmail
納得したらすぐにシェア!