Element

目次

はじめに

いよいよ本題です。このクラスは DHTML のレイヤー操作を
Netscape4.x , Netscape6 , Mozilla , Internet Explorer
間で分岐処理なしに操作してしまおうというクラスです。具体的には
if( document.all ){
    
    document.all["LAYER"].style.pixelLeft = x ;
    document.all["LAYER"].style.pixelTop  = y ;
    
    document.all["LAYER"].style.pixelWidth  = w ;
    document.all["LAYER"].style.pixelHeight = h ;
    
}else if( document.layers ){
    
    document.layers["LAYER"].moveTo( x , y );
    
    document.layers["LAYER"].resizeTo( w , h );
    
}else if( document.getElementById ){
    
    document.getElementById["LAYER"].style.left = x ;
    document.getElementById["LAYER"].style.top  = y ;
    
    document.getElementById["LAYER"].style.width  = w ;
    document.getElementById["LAYER"].style.height = h ;
    
}
Elements["LAYER"].setPosition( x , y );
Elements["LAYER"].setSize( w , h );
などと書けるようになります。 他クラスはこのクラスを作成するまでの布石といっても過言ではないです。レイヤーを汎用的に扱えるだけでなく、色々と面白い操作もあります。

このクラスでは Dimension クラスPoint3 クラスClient クラスを使用しています。

使用例

<script>

function init(){
    
    var element0 = new Element( "LAYER0" );
        element0.setPosition( 10 , 10 );
        element0.setSize( 200 , 100 );
        element0.setText( "このレイヤーの ID は"+element0.getID()+"です。" );
        
    status = element0.getWidth(); // 結果は 200
    
    var element1 = new Element( "LAYER1" );
    var p = new Dimension( 10 , 10 );
    
    with( element1 ){
        setVisibility( false );
        setPosition( p ); // ( 10 , 10 ) へ移動
        setHeight( 200 );
    }
}

</script>

<body onLoad="init();">
    
    <div id="LAYER0" style="position:absolute;">
    <div id="LAYER1" style="position:absolute;">
    
</body>

インスタンス変数

string     name  ; // レイヤー名
Layer      layer ; // レイヤー ( document.all["LAYER"] , document.layers["LAYER"]等 )
LayerStyle style ; // IE であれば document.all["LAYER"].style 等
name はレイヤーのIDです。 layer,style については 補足 で説明します。

クラス変数

int $user_create_element_number ; // 新規にレイヤーを生成した数

string[] index ; // Element クラスのクラスメンバについてで説明します。

コンストラクタ

Element();
Element( string name0 ); // name0 はレイヤー名
Element( Layer layer0 );
Element( Element element0 );
Element クラスのインスタンスを生成します。
3つ宣言の仕方がありますが、この中で一番使うのは Element( string name0 ) です。
例えば、HTML の BODY 部に以下のようなレイヤーがあるとします。
<div id="LAYER" style="position:absolute;"></div>
この場合、このレイヤーに対して Element クラスのインスタンスを生成するには
var element = new Element("LAYER");
です。これで LAYER に対して操作が出来るようになります。
問題は以下のような、レイヤーが入れ子の状態になっている場合です。
<div id="LAYER0" style="position:absolute;">
    <div id="LAYER1" style="position:absolute;">
        <div id="LAYER2" style="position:absolute;"></div>
    </div>
</div>
Internet Explorer であれば問題ないですが、Netcape4.x の場合、LAYER2 を取得するのは一般的に
var layer2 = document.layers["LAYER0"].document.layers["LAYER1"].document.layers["LAYER2"];
となります。考えただけでもウザイですね。
このため Element クラスではこれを自動で検索(取得)するようなプログラムを作成しています。
具体的には、Internet Explorer でも Netscape でも
var element2 = new Element("LAYER2");
で OK です。これでレイヤー LAYER2 に対して IE , NN で同じように処理してくれます。 階層がいくら深くても問題ありません。

次に Element( Layer layer0 ) です。
これは僕が Netscape4.x のテスト用に作った予備的なものであまり使わない(主旨に反する)ものでしょう。
具体的には以下のように記述します。
var element1 = new Element( document.layers["LAYER0"].document.layers["LAYER1"] );
みたいな感じです。つまり、レイヤーオブジェクトを直接指定します。
この場合、分岐処理が必要になりますね。 確実にレイヤーオブジェクトを取得したい場合に使用してください。

最後は引数なしの Element() です。Netscape4.x には
var layer = new Layer( width );
といった書き方が存在しますが、殆どこれと同じ操作になります。
つまり、新規にレイヤーを生成するということです。
var element = new Element();
と書くことで Netscape でも Internet Explorer でも新規にレイヤーを生成し、普通のレイヤーと同じように操作出来るようになります。
この場合のレイヤー名は Netscape4.x に準拠し、"_js_layer_+(生成した数-1)" となります。
例えば、一個この方法で生成した場合そのレイヤーの ID は _js_layer_0 となります。
生成したレイヤーの初期状態は 位置 : ( 0 , 0 )、サイズ : 0px×0px、可視属性 : hide(hidden) です。

Element( Element element0 ) は他クラス同様、引数を複製しますが、レイヤーを複製するという訳ではありません。
var element0 = new Element();
var element1 = new Element( "LAYER" );
var element2 = new Element( document.all["LAYER"] );
var element3 = new Element( element1 );

インスタンスメソッド

レイヤー名の参照 : getID
string getID();
レイヤー名を取得します。
var element = new Element( "LAYER" );

status = element.getID(); // 結果は LAYER
イコール : equals
boolean equals( string name0 );
boolean equals( Layer layer0 );
boolean equals( Element element0 );
自分自身が参照しているレイヤーと引数の参照しているレイヤーが等しいとき true を返します。
レイヤー名が等しいから、true を返すというわけではないので注意して下さい。
var element0 = new Element( "LAYER0" );
var element1 = new Element( "LAYER1" );

status = element0.equals( element1 ); // 結果は false
可視属性 : setVisibility , getVisibility
void setVisibility( boolean v );
boolean getVisibility();
レイヤーの可視属性を設定します。
set では引数 v が true のとき、visible(inherit) の状態になります。
get は状態が visible(inherit) のとき、true を返します。
element.setVisibility( false ); // hidden(hide)の状態になります。

status = element.getVisibility(); // 結果は false
背景色 : setBackgroundColor , getBackgroundColor
void setBackgroundColor();
void setBackgroundColor( string sColor );
void setBackgroundColor( Point3 pColor );

string getBackgroundColor();
レイヤーの背景色を設定、または取得します。
取得できる値は Internet Explorer に準拠し、16進数6桁のカラー文字列(ff0000など)です。
透明(透過)にしたい場合、引数を '' とするか、引数なしを使用して下さい。
この場合、getBackgroundColor で取得できる値は '' となります。
var red = "ff0000" ;
element0.setBackgroundColor( red );
status = element0.getBackgroundColor(); // 結果は ff0000

var blue = new Point3( 0 , 0 , 255 );
element1.setBackgroundColor( blue );
status = element1.getBackgroundColor(); // 結果は 0000ff

element2.setBackgroundColor(); // 透明になります。
status = element2.getBackgroundColor(); // 結果は ''
位置 : setPosition* , getPosition*
void setPositionX();
void setPositionX( number x0 );

void setPositionY();
void setPositionY( number y0 );

number getPositionX();
number getPositionY();
レイヤーの位置を設定、または取得します。
取得できる値は Netscape4.x に準拠し、( px を除く)純粋な数字が返されます。
set の場合、引数なしは left(top)=0 になります。
element0.setPositionX( 10 ); // X座標が10の位置へ移動
element0.setPositionY( 20 ); // Y座標が20の位置へ移動

status = "("+element0.getPositionX()+","+element0.getPositionY()+")"; // 結果は (10,20)
Zオーダー : setPositionZ , getPositionZ
void setPositionZ();
void setPositionZ( number z0 );

number getPositionZ();
レイヤーのZオーダーを設定、または取得します。
設定できる値は Netscape に準拠し、1 より小さい値は設定できないことになっています。 0 や負の値を設定しても 1 に補正されます。
set の場合、引数なしは 1 になります。
0 が設定できないのは Internet Explorer と Nescape で解釈が違うためです。
element0.setPositionZ(  2 );
element1.setPositionZ( -5 ); // 負の値を指定してみる

status = element0.getPositionZ() + " : " + element1.getPositionZ(); // 結果は 2 : 1
位置の一括指定、取得 : setPosition , getPosition , setPosition3 , getPosition3
void setPosition();
void setPosition( Dimension p0 );
void setPosition( number x0 , number y0 );

Dimension getPosition();
レイヤーの位置( X , Y )を一括指定、または取得します。
設定、取得には Dimension クラス を使用します。
set の場合、引数なしは top=0,left=0 となります。
void setPosition3();
void setPosition3( Point3 p0 );
void setPosition3( number x0 , number y0 , number z0 );

Point3 getPosition3();
上に加え、Z オーダーも設定、取得します。
設定、取得には Point3 クラス を使用します。
set の場合、引数なしは top=0,left=0,zIndex=1 となります。
var p0 = new Dimension( 10 , 100 );
element0.setPosition( p0 ); // ( 10 , 100 )へ移動します。
status = element0.getPosition(); // 結果は Dimension : ( 10 , 100 )

element1.setPosition( 10 , 100 , 1 ); // ( 10 , 100 )へ移動し、Z オーダーは 1 になります。
status = element1.getPosition3(); // 結果は Point3 : ( 10 , 100 , 1 )
重ね合わせ状態 : moveForward , moveBackward
void moveForward( string name0 );
void moveForward( Layer layer0 );
void moveForward( Element element0 );

void moveBackward( string name1 );
void moveBackward( Layer layer1 );
void moveBackward( Element element1 );
レイヤーの重ね合わせ状態を設定します。
moveForward  は引数で指定したレイヤーの前面へ
moveBackward は引数で指定したレイヤーの背面へ表示(移動)します。
Netscape の moveAbove , moveBelow と同じ働きをします。
引数で指定できる値は Element クラスのコンストラクタと同じ意味です。
var elementF = new Element("LAYER_F");
elementF.moveForward("LAYER");  // LAYER_F が、LAYER の前面に表示されます(移動します)。

var elementB = new Element("LAYER_B");
elementB.moveBackward("LAYER"); // LAYER_B が、LAYER の背面に表示されます(移動します)。
サイズ : setWidth , setHeight , getWidth , getHeight
void setWidth();
void setWidth( number w );

void setHeight();
void setHeight( number h );

number getWidth();
number getHeight();
レイヤーのサイズ(幅、高さ)を設定、または取得します。
取得できる値は Netscape に準拠し、(px を除く)純粋な数字です。
set の場合、引数なしは width(height)=0 になります。
element.setWidth( 100 );  // レイヤーの幅を 100px に設定
element.setHeight( 200 ); // レイヤーの高さを 200px に設定

status = element.getWidth() + " × " + element.getHeight(); // 結果は 100 × 200
サイズの一括指定、取得 : setSize , getSize
void setSize();
void setSize( Dimension size );
void setSize( number w , number h );

Dimension getSize();
レイヤーのサイズを一括指定、または取得します。
取得、設定には Dimension クラス を使用します。
set の場合、引数なしでは width=height=0 になります。
var size = new Dimension( 100 , 200 );
element.setSize( size ); // レイヤーのサイズが 100 × 200 になります。

status = element.getSize() // 結果は Dimension : ( 100 , 200 )
クリッピング : setTrim , getTrim
void setTrim();
void setTrim( number left , number top , number right , number bottom );
void setTrim( Dimension left_top , Dimension right_top );
レイヤーの表示領域を設定します。
Internet Explorer , Netscape の clip と同じです。
指定方法は Internet Explorer が「上→右→下→左」で、Netscape が「上→左→右→下」ですが、僕が分かりにくいので(笑)、ここでは 「左→上→右→下」 となります。
Dimension 指定では、第一引数で左上を、第2引数で右下の点を指定します。
引数なしでは、left=top=right=bottom=0 つまり、見えなくなります。
element0.setTrim( 10 , 20 , 30 , 40 ); // (10,20)-(30,40) の矩形領域がクリッピングされます。
element1.setTrim( new Dimension( 10 , 20 ) , new Dimension( 30 , 40 ) ); // 上に同じ
number[] getTrim();
number setTrim( number p );
レイヤーのクリップ値を取得します。
引数なしではクリップ値 left , top , right , bottom の4つを値に持つ配列で取得します。
setTrim( number p ) は p で取得する値を指定し、0 のとき left、1 のとき top、2 のとき right、 3 のとき bottom の値が取得できます。
element0.setTrim( 10 , 20 , 30 , 40 );

status = element0.getTrim();  // 結果は 10,20,30,40
status = element0.getTrim(1); // 結果は 20
画像の取得 : getImage
Image[] getImage();
Image getImage( number index );
Image getImage( string id );
レイヤー内に存在する Image オブジェクトを取得します。
引数なしの getImage はレイヤー内の全Imageオブジェクトを配列に格納したものを取得します。
getImage( number index ) は (index-1)番目に存在する Image オブジェクトを取得します。
getImage( string id ) は引数で指定した name 属性を持つ画像を取得します。
分かり難いですか?下の例を見て掴んで下さい。
<script>

function init(){
    
    var text = "" ;
    var e = new Element( "LAYER" );
    
    // images に全Imageオブジェクトを配列にしたものを格納
    var images = e.getImage();
    
    for(var i=0;i<images.length;i++) text += images[i].src + "\n" ;
    
    alert( text );
    // 結果は
    // http://.../image0.jpg
    // http://.../image1.jpg
    // http://.../image2.jpg
    
    var imageFromNumber = e.getImage(1);
    
    alert( imageFromNumber.src ); // 結果は http://.../image1.jpg
    
    var imageFromId = e.getImage( "IMG0" );
    
    alert( imageFromId.src ); // 結果は http://.../image0.jpg
    
}

</script><body onLoad="init();">

<span id="LAYER" style="position:absolute;">
    
    <img src="image0.jpg" name="IMG0">
    
    <a href="#"><img src="image1.jpg"></a>
    
    <img src="image2.jpg">
    
</span>;

</body>
レイヤーが入れ子のとき、取得する順番が違い、クロスな値が得られませんので注意して下さい。
Netscape では、入れ子のレイヤーに存在する Image オブジェクトを、取得せずに無視しますので注意して下さい。入れ子のレイヤー内に Image オブジェクトが存在しなければ問題ありません。
テキスト : setText
void setText();
void setText( string text );
レイヤー内のテキスト(内容)を書き換えます。 Internet Explorer の innerHTML と同じ働きをします。 引数なしの場合、内容がクリアされます。
var html_text = "<span style='color:#ff0000'>あいうえお<\/span>" ;

element.setText( html_text ); // レイヤーの内容が赤色で「あいうえお」になります。
外部ファイル : setFile
void setFile( string filename ); // filename は HTML ファイル名
レイヤー内に HTML ファイルを読み込みます。Netscape の Layer.src と同じ働きをします。
Internet Explorer , Nescape6 , Mozilla ではテキスト内に IFRAME タグ を無理矢理挿入するため不安定な部分が多いです。
element.setFile( "index.html" ); // レイヤーの内容が index.html になります。
標準出力文字列 : toString
string toString();
Element クラスの標準出力文字列を返します。
返される文字列は "Element : " + this.name です。
var element = new Element( "LAYER" );

status = element ; // 結果は Element : LAYER

クラスメソッド

Elements 配列の初期化
void setElementArray();
非常に便利なクラスメソッドなので Element クラスのクラスメンバについて↓ で詳しく説明します。

Element クラスのクラスメンバについて

Element クラスのクラス(static)メンバには、プロパティに string[] index , メソッドに void setElementArray が存在します。
特に setElementArray メソッドは非常に便利です。 使い方も簡単なので、必ずこの項は読んでください。

今まで Element クラスを使用するためには( BODY部に ID が LAYER のレイヤーがある場合)
var element = new Element("LAYER");
として、レイヤーを操作していました。
しかし、これではレイヤーが多数存在する場合、この操作をレイヤーの数だけ記述しなくてはいけません。
・・・だるいですね。ということでこのメソッドの登場です。
このメソッドを使えば、BODY 部に存在する全てのレイヤーに対して上記の操作を自動で行ってくれます。
具体的には以下のように new することなくレイヤーを扱うことが可能です。
例えば、BODY 部に以下のようなレイヤーが存在する場合、
<div id="LAYER0" style="position:absolute;"></div>
<div id="LAYER1" style="position:absolute;"></div>
<div id="LAYER2" style="position:absolute;"></div>
<div id="LAYER3" style="position:absolute;"></div>
このレイヤーを操作するためには
Element.setElementArray();
を呼び出し、new することなくいきなり
Elements["LAYER0"].setPosition( 10 , 10 );
Elements["LAYER1"].setPosition( 20 , 20 );
Elements["LAYER2"].setPosition( 30 , 30 );
Elements["LAYER3"].setPosition( 40 , 40 );
というふうに Elements という配列をあたかも Internet Explorer や Netscape4 , Netscape6 の document.all["LAYER0"] , document.layers["LAYER0"] , document.getElementById("LAYER0") のように扱うことが可能になります。
そして、ここでもレイヤーの入れ子が問題になります。
BODY 部に以下のようなレイヤーが存在する場合、
<div id="LAYER0" style="position:absolute;">
    <div id="LAYER1" style="position:absolute;">
        <div id="LAYER2" style="position:absolute;"></div>
    </div>
</div>
Netscape4.x では、レイヤー LAYER2 を取得、操作するには
var layer2 = document.layers["LAYER0"].document.layers["LAYER1"].document.layers["LAYER2"];
でしたが、このクラスを使用すると、IE の document.all["LAYER2"] と同じように
Elements["LAYER2"];
だけでよくなります。これだけで、Netscape4.x の document.layers["LAYER0"].document.layers["LAYER1"].document.layers["LAYER2"] と同じです。
使用例を書いておきます。
<script>

function init(){
    
    Element.setElementArray(); // 配列 Elements に全てのレイヤーを挿入(初期化)
    
    Elements["LAYER0"].setPosition( 10 , 10 );
    
    with( Elements["LAYER1"] ){
        setPosition( 10 ,10 );
        setSize( 100 , 100 );
        setText("入れ子になっているレイヤーです");
    }
    
}

</script>

<body onLoad="init();">
    
    <div id="LAYER0" style="position:absolute;">
        <div id="LAYER1" style="position:absolute;"></div>
    </div>
    
</body>
次にメンバ変数 string[] index についてですが、
この配列はメソッド setElementArray で生成した時点での全てのレイヤー名(言い換えれば BODY 部に存在する全てのレイヤー名)を値として保持しています。
例えば、以下のようなレイヤーが BODY 部に存在する場合、
<div id="LAYER" style="position:absolute;"></div>

<div id="LAYER0" style="position:absolute;">
    <div id="LAYER1" style="position:absolute;">
        <div id="LAYER2" style="position:absolute;"></div>
    </div>
</div>
index[] の中身は
index[0] = "LAYER" ;
index[1] = "LAYER0" ;
index[2] = "LAYER1" ;
index[3] = "LAYER2" ;
となります。これは使い方(場合)によってはかなり使えます。
例えば、全てのレイヤーのサイズを 100 × 100 に設定したい場合、
for(var i=0;i<Element.index.length;i++){
    Elements[ Element.index[i] ].setSize( 100 , 100 );
}
とかいうふうに記述できるようになります。
for(var i=0;i<Elements.length;i++){
    Elements[i].setSize( 100 , 100 );
}
とは出来ませんので注意して下さい。

メソッド一覧

Element クラスで使用できるメソッドのリストです。
メソッド名説明
stringgetIDレイヤー名の取得
booleanequals等しいか判定
voidsetVisibility可視属性の設定
booleangetVisibility可視属性の取得
voidsetBackgroundColor背景色の設定
stringgetBackgroundColor背景色の取得
voidsetPositionX位置X座標(left)の設定
voidsetPositionY位置Y座標(top)の設定
voidsetPositionZZオーダー(zIndex)の設定
numbergetPositionX位置X座標(left)の取得
numbergetPositionY位置Y座標(top)の取得
numbergetPositionZZオーダー(zIndex)の取得
voidsetPosition位置X,Yの一括指定
DimensiongetPosition位置X,Yの一括取得
voidsetPosition3位置X,Y,Zオーダーを一括して設定
Point3getPosition3位置X,Y,Zオーダーを一括して取得
voidmoveForward指定したレイヤーの前面へ移動
voidmoveBackward指定したレイヤーの背面へ移動
voidsetWidth幅(width)の設定
voidsetHeight高さ(height)の設定
numbergetWidth幅(width)の取得
numbergetHeight高さ(height)の取得
voidsetSizeサイズを一括して設定
DimensiongetSizeサイズを一括して取得
Image([])getImage画像の取得
voidsetTrimクリッピング
number([])getTrimクリップ値の取得
voidsetTextレイヤー内容の書き換え
voidsetFileレイヤー内に HTML ファイルを読み込む
stringtoString標準出力文字列
クラスメソッド
voidsetElementArrayElements 配列の初期化

補足

■ インスタンス変数 layer , style
使い方によっては勿論、上記に示したメソッド以外の値を設定したい場合があります。
例えば、Netscape4 では使えない、フォント種を設定したい場合や display 値を設定したい場合です。その場合、Element クラスのインスタンス変数 layer を使うと良いです。具体的には例えば
var element = new Element( "LAYER" );
    (element.layer).style.fontFamily = "IMPACT";
    (element.layer).style.display = "none";
と書くことができます。つまり、Element クラスのインスタンス変数 layer は IE でいう document.all["LAYER"] と等価になります。
Netscape4 では element.layerdocument.layers["LAYER"],
Netscape6 , Mozilla では document.getElementById("LAYER") と等価です。
レイヤーが入れ子の場合でも document.layers["LAYER0"].document.layers["LAYER1"] 等と等価です。

インスタンス変数 style はこれを短縮するもので Internet Explorer , Netscape6 で上記と同じことをしたい場合、
var element = new Element("LAYER");
    element.style.fontFamily = "IMPACT";
    element.style.display = "none";
と記述できます。つまり、インスタンス変数 style は Internet Explorer では document.all["LAYER"].style と等価になります。Netscape6 , Mozilla でも同様です。
Netscape4 ではこのインスタンス変数 stylelayer と同じで document.layers["LAYER"] と等価になります。
■ こんな使い方も出来ます( オブジェクトの省略 this )
DHTML サイトでは↓のような書き方をよく見かけます。
<div id="LAYER" onClick="moveLayer( this , 20 , 200 );"></div>
オブジェクトの省略を表す this を使ったものです。Element クラスのメソッドにもこの書き方が使えないでしょうか?
しいて書くなら、
<div id="LAYER" onClick="this.setPosition( 20 , 200 );"></div>
のような書き方です。流石にこうは書けませんが、↓のようには書けます。
<div id="LAYER" onClick="new Element( this ).setPosition( 20 , 200 );"></div>
■ 他にもメソッドが・・・
ここで説明した以外にもメソッドは存在します。ソースを見て貰えれば分かりますが、
レイヤーの背景画像を設定する setBackgroundImage
レイヤーの位置、サイズを初期化する initPosition , initSize
これらは「僕が使わない」や「クロスしていない」等の理由で説明していません。
ただし、initPosition,initSize については内部で利用しているので変更しないで下さい。
■ 私的な使い方
勿論、独自にメソッドを追加して使うなんてこともありです。僕はこれらのメソッドにさらに以下のようなメソッドを追加しています。

レイヤーの右上端の座標を取得する getPositionUR
レイヤーの右下端の座標を取得する getPositionBR
レイヤーの左下端の座標を取得する getPositionBL
レイヤーの中心の座標を取得する getPositionC
レイヤー位置を右上端で指定する setPositionUR
レイヤー位置を右下端で指定する setPositionBR
レイヤー位置を左下端で指定する setPositionBL
レイヤー位置をレイヤーの中心座標で指定する setPositionC (これはかなり使える)
レイヤーのクリップを left と right で指定する setTrimX
レイヤーのクリップを top と bottom で指定する setTrimY

などです。自分の使い易いように拡張して下さい。
「レイヤーのクリップを%で指定できる」とかも面白そうですね。