2012年1月10日火曜日

Titanium の WebView で jQuery 読み込み時の遅延

すげーハマってました。
なかなかどうして難しいですね。

なんだろう。単純に考えると、

var win = Ti.UI.createWindow();
var wv  = Ti.UI.createWebView({url:"html/test.html");
win.add(wv);
win.open();
wv.addEventListener("load",function(){
 wv.evalJS("testFunc()");
});

ってやれば、WebViewであるwvの読み込み完了時に、
WebView で読み込んでいる test.html に記述された testFunc() が実行されるんだけど、
その test.html を読み込んだからといって、
test.html で script src してる CDN 上の jQuery.js の読み込みが完了していないっていう場合があるっぽい。
testFunc内で、$ とか使っていて、jQuery の読み込みが終わっていなければ、当然実行エラーになる。

んで、最初はどうしたかというと、
html/jQuery.js みたいに、ローカルにおいて、それを読み込めばいいじゃん!って思った。
しかしながら、なんか、Titanium で アプリを Deploy (製品状態にコンパイルする)時に、
jQuery.js でコンパイルエラーみたいになってうまくいかなかった。
仕方が無いから、 html/test.html に、 jQuery.js の中身を書いてやれ!と思って書いたんだけど、
今度は test.html のコンパイルエラーみたいになった。
まぁ、読み込んでいたのが jQuery1.6.2 だったからなのかもしれないけど。

仕方が無いので、wv.addEventListener() を書き換えました。

var win = Ti.UI.createWindow();
var wv  = Ti.UI.createWebView({url:"html/test.html");
win.add(wv);
win.open();
wv.addEventListener("load",function(){
 var timer = setInterval(function(){
  var jQReady = wv.evalJS("$.isReady");
  if(jQReady){
   clearInterval(timer);
   wv.evalJS("testFunc()");
  }
 },100);
});

0.1秒毎にjQueryの準備が出来たかどうかを返す、$.isReady を WebView に投げて、
jQuery の読み込みが無ければ $ もなにも無いんで、何も返ってこないんだけど、
読み込みが完了したら true が返るので、
そしたらタイマーをはずして testFunc を実行するようにしてみた。
一応は、動いてはいるんだけど、大丈夫かなー。
Android は、なんだか動きが良くわかりません。機種ごととかによって違うのかもだし。

1 件のコメント:

  1. 私はWebViewのロード終了時に、
    WebViewのJavascriptからTitanium 側のjavascriptにイベントを渡してあげました。

    イベントの渡す方法は下記URLを参照
    http://akabeko.me/blog/2010/11/titanium-%E3%81%AE-webview-%E3%81%A7-html-%E3%82%92%E3%83%9B%E3%82%B9%E3%83%88/

    iOS(3GS,4,4S)の場合はこの方法で上手く動いています。

    ちなみに、Androidの場合実装法によってはWebViewとのイベント受け渡しに問題が発生する場合があります。

    参考までに

    返信削除