OpenLaszloでマルチデバイス対応RIAを作ろう

第6回 スクリプトの記述形式

この記事を読むのに必要な時間:およそ 7 分

idとname,オブジェクト指定方法

これまでのサンプルでもしょっちゅう出ていたので何となくご理解いただいているかもしれませんが,idとname,およびオブジェクトの指定方法について説明します。ここでいうオブジェクトとは簡単に言うとタグのことです。

あるタグに対して動作させたり属性値を取得したりするにはそのタグを指定しなければなりません。そのタグを指定するためにid属性やname属性で名前を付けます。nameは同一階層でのみ重複しなければ良く,idはアプリ内で重複してはいけない,という違いがあります。さらに,nameはLZXの階層構造を意識した階層的な指定が必要なのに対し,idはその名前のみの直指定でOKという違いがあります。

nameの場合の指定方法

nameの場合,相対指定と絶対指定があります。相対指定は階層上の自身の位置から相手の位置へのパスを指定します。ファイルシステムでいうと「../../tmp」のような指定の仕方です。一方,絶対指定はルート要素のcanvasから降りていくパスを指定します。ファイルシステムでいうと「/usr/local/tmp」のようにルートディレクトリからフルパスで指定するのと同じです。

自分自身はthisで指定します。

階層構造の親子関係の中では親は1つなので名前を指定する必要はなくparentで指定できます。親の親はparent.parentで,2階層上にあがることを意味します。

親の子,つまり兄弟タグは複数存在できるので名前で識別するしかありません。そのためにnameで名前を付けます。もちろん兄弟だけでなく親の親の子,親の兄弟の子など識別するためにはすべて名前が必要です。

リスト11ではA,Bのビューは兄弟タグなので同じ名前は使えませんが,それぞれの子ビューa,b,cは階層が違うので同じ名前が使えます。

表1 リスト11の階層構造での指定方法

指定の内容相対指定絶対指定
(1)から(2)this.bcanvas.A.a.b
(1)から(3)this.b.ccanvas.A.a.b.c
(1)から(5)parent.parent.B.a.b.ccanvas.B.a.b.c
(3)から(1)parent.parentcanvas.A.a
(3)から(2)parentcanvas.A.a.b
(3)から(4)parent.dcanvas.A.a.b.d
(5)から(3)parent.parent.parent.parent.A.a.b.ccanvas.A.a.b.c

リスト11 nameと階層構造

<view name="A">
  <view name="a"> (1)
    <view name="b"> (2)
      <view name="c">  (3)
      </view>
      <view name="d">  (4)
      </view>
    </view>
  </view>
</view>
<view name="B">
  <view name="a">
    <view name="b">
      <view name="c"> (5)
      </view>
    </view>
  </view>
</view>

リスト12 nameの例

<canvas proxied="false" bgcolor="0xffffcc"> 
  <window title="ウインドウ2" name="win2" y="150" width="200" height="100">
    <method name="moveRight">//メソッド1
      this.animate('x',20,300,true);
    </method>
  </window>
  <window title="ウインドウ1" width="300">
    <method name="moveRight">//メソッド2
      this.animate('x',20,300,true);
    </method>
    <simplelayout spacing="4"/>
    <button text="(1)ウインドウ1を動かす" onclick="parent.moveRight()"/>
    <button text="(2)ウインドウ2を動かす" onclick="parent.parent.win2.moveRight()"/>
    <button text="(3)このボタンを動かす" onclick="this.moveRight()">
      <method name="moveRight">//メソッド3
        this.animate('x',20,300,true);
      </method>
    </button>
  </window>
</canvas>

リスト12サンプル

リスト12では全く同じ内容の自作メソッドmoveRight()が3ヶ所に記述されています。moveRight()自体は自分自身を右に動かす処理が書かれています。

ボタン(1)はparent.moveRight()となっているので,親のmoveRight()つまりメソッド2が実行されます。

ボタン(2)はparent.parent.win2.moveRight()で,親の親の子win2のmoveRight()つまりメソッド1が実行されます。

ボタン(3)はthis.moveRight()なので自分自身のmoveRight()が実行されます。

moveRight()メソッド内のthisは<method>自身ではなく<method>が定義されている親タグのことを指します。<method>自身はビューではなく親タグの付属物であり,つまり親タグ自身であるということになっているためです。この点は<handler>についても<method>と同じです。これらはソースの見た目の階層構造と異なるので注意が必要です。

※ここで出ているanimate()はアニメーション処理をするメソッドです。this.animate('x',20,300,true)とは,⁠x」属性の値を「20」ピクセルに「300」ミリ秒かけて変化させるという意味です。最後の「true」は変化後の値に対して相対的に動くという意味です。falseだとx=20になりますが,trueだとx値が20ずつ増加することになります。アニメーション系は後の記事で解説します。

idの指定方法

idを使う場合,アプリ内で重複しないたった1つの名前を設定します。idで名前を付けられたタグを指定するには階層構造を一切気にすることなくその名前のみでOKです。

リスト13はリスト11と同じですが,idで付けた名前は重複できないのでビューBの子ビュー達の名前をa,b,c,からe,f,gに変えています。表2では表1と異なり名前のみで超簡単に指定できることがわかります。相対指定だと階層構造が変わったときにparent.parent・といった記述の修正が大変なので,問題がない限りid指定で良いでしょう。筆者も基本的にidを使っていますし,本連載記事に出てくるサンプルコードもほとんどid指定です。

表2 リスト13の階層構造での指定の方法

(1)から(2)b
(1)から(3)c
(1)から(5)g
(3)から(1)a
(3)から(2)b
(3)から(4)d
(5)から(3)c

リスト13 idと階層構造

<view id="A">
  <view id="a"> (1)
    <view id="b"> (2)
      <view id="c">  (3)
      </view>
      <view id="d">  (4)
      </view>
    </view>
  </view>
</view>
<view id="B">
  <view id="e">
    <view id="f">
      <view id="g"> (5)
      </view>
    </view>
  </view>
</view>

リスト14はリスト12の相対指定の部分をid指定に変更したものです。リスト12との変更点は2ヶ所で,2行目のウインドウ2のnameをidに,13行目のボタン(2)の相対指定(parent.parent.win2.moveRight())を絶対指定(win2.moveRight())に変えています。

リスト14 idの例

<canvas proxied="false" bgcolor="0xffffcc"> 
  <window title="ウインドウ2" id="win2" y="150" width="200" height="100">
    <method name="moveRight">//メソッド1
      this.animate('x',20,300,true);
    </method>
  </window>
  <window title="ウインドウ1" width="300">
    <method name="moveRight">//メソッド2
      this.animate('x',20,300,true);
    </method>
    <simplelayout spacing="4"/>
    <button text="(1)ウインドウ1を動かす" onclick="parent.moveRight()"/>
    <button text="(2)ウインドウ2を動かす" onclick="win2.moveRight()"/>
    <button text="(3)このボタンを動かす" onclick="this.moveRight()">
      <method name="moveRight">//メソッド3
        this.animate('x',20,300,true);
      </method>
    </button>
  </window>
</canvas>

リスト14サンプル

setAttribute()

スクリプトを記述するときに頻出するメソッドsetAttribute()について説明しておきます。このメソッドは文字通りattribute(=属性)をset(設定)するものです。

文法的にはsetAttribute(属性名,値)となります。たとえばx属性の値を100にするにはsetAttribute('x',100),width属性の値を200にするにはsetAttribute('width',200)と書きます。

setAttribute()の超重要な機能としては,実行時に「on+属性名」のイベントが自動的に発生する点です。setAttribute('x',100)実行時には「onx」イベントが,setAttribute('width',200)実行時には「onwidth」イベントが発生します。それをイベントハンドラで受信して何か処理をする,というイベント駆動のプログラムを書くことができます。イベントが電波で,イベントハンドラがアンテナのようなイメージです。

リスト15サンプルのボタンを押すと縦向きの赤青黄のビューが位置を変えて横向きになります。ボタンクリック時にボタン自身のx値を変えただけ(1)なのですが,onxというイベントが発生したために他のビューに次々と影響(2)(3)(4)を与えています。

※ <handler>にあるreference属性には,拾いたいイベントが発生するタグ名を指定します。referenceがなければデフォルト動作として親タグのイベントに反応しますが,referenceがあれば親タグではなく指定されたタグのイベントに反応します。

リスト15 setAttribute()とイベントハンドラ

<canvas proxied="false" bgcolor="0xffffcc">
  <button id="btn">
    <handler name="onclick">
      this.setAttribute('x',100); // (1)
    </handler>
  </button>
  <view id="v1" y="30" width="20" height="20" bgcolor="red">
    <handler name="onx" reference="btn">  // (2)
      this.setAttribute('x',20);
      this.setAttribute('y',50);
    </handler>
  </view>
  <view id="v2" y="50" width="20" height="20" bgcolor="yellow">
    <handler name="onx" reference="v1">  // (3)
      this.setAttribute('x',40);
      this.setAttribute('y',50);
    </handler>
  </view>
  <view id="v3" y="70" width="20" height="20" bgcolor="blue">
    <handler name="ony" reference="v2">  // (4)
      this.setAttribute('x',60);
      this.setAttribute('y',50);
    </handler>
  </view>
</canvas>

リスト15サンプル

(1)・ボタンクリック時にボタンのxを100に変更(=右に移動する)。→ ボタンbtnにonxイベントが発生する。

(2)・ボタンbtnのonxイベントを受信して実行。→ ビューv1にonxイベント,onyイベントが発生する。

(3)・ビューv1のonxイベントを受信して実行。→ ビューv2にonxイベント,onyイベントが発生する。

(4)・ビューv2のonyイベントを受信して実行。→ ビューv3にonxイベント,onyイベントが発生するがそれを受信するイベントハンドラはどこにもないので無視される。

著者プロフィール

ason(あそん)

京都の在宅ITエンジニア。サーバやネットワーク系が得意。初めて触った言語はOpenLaszlo。現在WebプログラマとしてHTML,CSS,PHP,CMSに詳しくなってきたところ。デスメタルドラマー。

URL:http://xtter.openlaszlo-ason.com/