2013年6月5日水曜日

TitaniumでDOMみたいに要素を探す方法

  • このエントリーをはてなブックマークに追加

TitaniumはもちろんDOMではないので、
普通のhtmlみたいにdocument.getElementById("hoge")みたいにすることは出来ない。

というかそもそも作りとしてはvar btn = Ti.UI.createButton()みたいにやるので、
コンテキストは変数に保持されているから問題ないんだけれども、
そういう風に作るからこそソースを分ける事が出来なくて汚くなってしまう。
かといって分けてしまうと作り方によってはコンテキストの指定が出来ないという問題も出てしまう。
ということでそれらを解消してjQueryみたいに$("#hoge")や$(".foo")みたいに指定する方法を書いてみる。

■探すためのfunction

function find(_string,_context,_c){
  var c = (_c)?_c:[];
  var childs = _context.getChildren();
  
  if(_string.match(/^\#/)){
    var ext = "id";
    _string = _string.replace(/\#/,"");
  }
  else if(_string.match(/^\./)){
    var ext = "class";
    _string = _string.replace(/\./,"");
  }
  else{
    console.log("_string is not defiend or not ^# or not ^.");
    return false;
  }

  for(var i in childs){
    if(childs[i].$$[ext]){
      if(childs[i].$$[ext] == _string){
        c.push(childs[i]);
        if(ext == "id") return c[0];
      }
    }
  }

  return c;
}
■適当なサンプル
var view = Ti.UI.createView();
var btn = Ti.UI.createButton({
  title:"This is a button",
  top:30,
  $$:{
    id:"hoge"
  }
});
var label1 = Ti.UI.createLabel({
  text:"label1",
  top:70,
  $$:{
    class:"foo"
  }
});
var label2 = Ti.UI.createLabel({
  text:"label2",
  top:110,
  $$:{
    class:"foo"
  }
});

view.add(btn);
view.add(label1);
view.add(label2);

var hoge = find("#hoge",view);
hoge.addEventListener("click",function(e){
  alert(e.source.title);
});

var labels = find(".foo",view);
labels[0].text = "label1 text is replaced";
labels[1].text = "this is a label2";

要素を探し出してそれに直接clickイベントをつけたり、
テキスト要素の書き換えを行っている感じ。

ちなみにそれぞれ要素に対して、$$["id"]もしくは$$["class"]というのを持たせている。
これが正解かどうかはわからないけど、
グローバルな部分と被らなければいいかなってことで$$というのにした。
作り込んでいないので第二引数で指定したコンテキストの子要素だけしか探せない。
なので孫要素などは引っ張ってこれないのは要注意。
でもTitanium3.0になってからはAlloyが標準で入れられるようになったし、
わざわざこんな感じで記述しなくてもMVC的に分離出来るから問題ないんだけど。
人によってはTitanium2でずっと作ってて、
3にしたら不具合出るのを嫌うとかそういう人向けではあるかもしれない。

とりあえずはTitanium3でAlloy使うのが今のところの最善策じゃなかろうかと。

Adsense