Cross Browser のための DHTML


・スライドオブジェクト

「DHTML版 Marquee」と同じ技術( 実装は全く異なりますが ^^; )で スライドショーのような動作をさせることができます。

実行中...
1.左->右
2.上->下
3.右->左
4.下->上
5.中央->左右
6.中央->上下
7.左上->右下
8.右上->左下
9.右下->左上
10.左下->右上
11.中央->周囲
12.左->右
13.上->下
14.右->左
15.下->上
16.左上->右下
17.右上->左下
18.右下->左上
19.左下->右上

上のサンプルはこのページで紹介する Slide オブジェクトでサポートしている 19種類の動作のデモで、 「表示」ボタンを操作すると 19個のレイアを順番にそれぞれ異なった動作で表示します。 「消去」ボタンを操作すると逆順逆動作でレイアを消去していきます。

以下は Slide オブジェクトのコードです。

<script language="JavaScript1.2"><!--
// スライドオブジェクト
//   new Slide(div,times);
//       div      : 対象レイア
//       times    : フレーム数
function Slide(div,times){
  this.div     = div;   // 対象レイア
  this.times   = times; // フレーム数
  this.counter = 0;     // 実行カウンタ
  this.dir     = true;  // 表示方向( true=表示, false=消去 )

  // レイアの初期位置とサイズ
  this.x      = getDivLeft  (div);
  this.y      = getDivTop   (div);
  this.width  = getDivWidth (div);
  this.height = getDivHeight(div);

  // 現在の表示位置とサイズ
  this.clipX    = this.x; this.clipY      = this.y;
  this.clipTop  = 0;      this.clipBottom = this.height;
  this.clipLeft = 0;      this.clipRight  = this.width;
  this.horzClip = null;   this.vertClip   = null;
  this.horzPos  = null;   this.vertPos    = null;

  // コールバック定義
  this.actionCallback = null; this.actionClientData = null;
  this.endCallback    = null; this.endClientData    = null;
}
//
// クリップ領域算出メソッド( 内部メソッド )
//
//   右から左
Slide.prototype.leftToRight = function(dir){
  this.clipRight = this.width
                 *(this.dir?
                   this.counter:(this.times-this.counter))
                 /this.times;
}
//   左から右
Slide.prototype.rightToLeft = function(dir){
  this.clipLeft = this.width
                *(this.dir?
                 (this.times-this.counter):this.counter)
                /this.times;
}
//   中央から左右
Slide.prototype.centerToLeftRight = function(dir){
  var w = this.width
        *(this.dir?
          this.counter:(this.times-this.counter))
        /this.times;
  this.clipLeft  = (this.width-w)/2;
  this.clipRight = this.width-this.clipLeft;
}
//   上から下
Slide.prototype.topToBottom = function(dir){
  this.clipBottom = this.height
                  *(dir?
                    this.counter:(this.times-this.counter))
                  /this.times;
}
//   下から上
Slide.prototype.bottomToTop = function(dir){
  this.clipTop = this.height
               *(dir?
                (this.times-this.counter):this.counter)
               /this.times;
}
//   中央から上下
Slide.prototype.centerToTopBottom = function(dir){
  var h = this.height
        *(dir?
          this.counter:(this.times-this.counter))
         /this.times;
  this.clipTop    = (this.height-h)/2;
  this.clipBottom = this.height-this.clipTop;
}
//
// 表示位置算出メソッド( 内部メソッド )
//
//   左から右
Slide.prototype.leftToRightPos = function(dir){
  this.clipX = this.x-this.clipLeft;
}
//   右から左
Slide.prototype.rightToLeftPos = function(dir){
  this.clipX = this.x+this.width-this.clipRight;
}
//   上から下
Slide.prototype.topToBottomPos = function(dir){
  this.clipY = this.y-this.clipTop;
}
//   下から上
Slide.prototype.bottomToTopPos = function(dir){
  this.clipY = this.y+this.height-this.clipBottom;
}
// スライド動作登録メソッド
// registerAction(action)
//   action : 動作の種類
       // クリップのみ
       Slide.LEFT_TO_RIGHT             = 0x0100; // 左->右
       Slide.TOP_TO_BOTTOM             = 0x0001; // 上->下
       Slide.RIGHT_TO_LEFT             = 0x0200; // 右->左
       Slide.BOTTOM_TO_TOP             = 0x0002; // 下->上
       Slide.CENTER_TO_LEFTRIGHT       = 0x0300; // 中央->左右
       Slide.CENTER_TO_TOPBOTTOM       = 0x0003; // 中央->上下
       Slide.LEFTTOP_TO_RIGHTBOTTOM    = 0x0101; // 左上->右下
       Slide.RIGHTTOP_TO_LEFTBOTTOM    = 0x0201; // 右上->左下
       Slide.RIGHTBOTTOM_TO_LEFTTOP    = 0x0202; // 右下->左上
       Slide.LEFTBOTTOM_TO_RIGHTTOP    = 0x0102; // 左下->右上
       Slide.CENTER_TO_ROUND           = 0x0303; // 中央->周囲
       // クリップとスライド
       Slide.LEFT_TO_RIGHT_IN          = 0x1200; // 左->右
       Slide.TOP_TO_BOTTOM_IN          = 0x0012; // 上->下
       Slide.RIGHT_TO_LEFT_IN          = 0x2100; // 右->左
       Slide.BOTTOM_TO_TOP_IN          = 0x0021; // 下->上
       Slide.LEFTTOP_TO_RIGHTBOTTOM_IN = 0x1212; // 左上->右下
       Slide.RIGHTTOP_TO_LEFTBOTTOM_IN = 0x2112; // 右上->左下
       Slide.RIGHTBOTTOM_TO_LEFTTOP_IN = 0x2121; // 右下->左上
       Slide.LEFTBOTTOM_TO_RIGHTTOP_IN = 0x1221; // 左下->右上
Slide.prototype.registerAction = function(action){
  switch(action&0x0F){         // 上下のクリップ領域計算
  case 1:  this.vertClip = this.topToBottom;       break;
  case 2:  this.vertClip = this.bottomToTop;       break;
  case 3:  this.vertClip = this.centerToTopBottom; break;
  default: this.vertClip = null;                   break;
  }
  switch((action>>8)&0x0F){    // 上下の位置
  case 1:  this.horzClip = this.leftToRight;       break;
  case 2:  this.horzClip = this.rightToLeft;       break;
  case 3:  this.horzClip = this.centerToLeftRight; break;
  default: this.horzClip = null;                   break;
  }
  switch((action>>4)&0x0F){    // 左右のクリップ領域
  case 1:  this.vertPos = this.topToBottomPos; break;
  case 2:  this.vertPos = this.bottomToTopPos; break;
  default: this.vertPos = null;                break;
  }
  switch((action>>12)&0x0F){   // 左右の位置
  case 1:  this.horzPos = this.leftToRightPos; break;
  case 2:  this.horzPos = this.rightToLeftPos; break;
  default: this.horzPos = null;                break;
  }
}
// 通知関数登録メソッド
// registerCallback(k,func,data)
//   k    : 登録する種類
            Slide.ACTIONCALLBACK = 1; // 実行通知
            Slide.ENDCALLBACK    = 2; // 終了通知
//   func : 登録する関数
//   data : 呼び出し時のデータ
Slide.prototype.registerCallback = function(k,func,data){
  switch(k){
  case 1:
    this.actionCallback = func; this.actionClientData = data;
    break;
  case 2:
    this.endCallback    = func; this.endClientData    = data;
    break;
  }
}
// 動作初期化メソッド
// initAction(dir)
//   dir : 方向
//         true  : 順方向( 表示方向 )
//         false : 逆方向( 消去方向 )
Slide.prototype.initAction = function(dir){
  this.counter = 0;
  this.dir     = dir;
}
// 実行メソッド
// doAction()
Slide.prototype.doAction = function(){
  if(this.counter>=this.times) return true;
  this.counter++;
  if(this.horzClip) this.horzClip(this.dir);
  if(this.vertClip) this.vertClip(this.dir);
  var needMove = false;
  if(this.horzPos){ this.horzPos(this.dir); needMove = true; }
  if(this.vertPos){ this.vertPos(this.dir); needMove = true; }
  if(!this.dir && this.counter==this.times){
    setDivVisibility(this.div,false);
  } else {
    setDivClip(this.div,
               this.clipTop,this.clipRight,
               this.clipBottom,this.clipLeft);
    if(this.dir && this.counter==1)
      setDivVisibility(this.div,true);
  }
  if(needMove) moveDivTo(this.div,this.clipX,this.clipY);
  if(this.counter==this.times && this.endCallback)
    this.endCallback(this,this.endClientData);
  else if(this.actionCallback)
    this.actionCallback(this,this.actionClientData);
  return (this.counter==this.times);
}
// --></script>

この文字の部分は「ライブラリ集」で紹介している関数です。 上のスクリプトでは記述されていませんので、 使用する際には「ライブラリ集」を参照して追加してください。

Slide オブジェクトのメソッドとプロパティを以下に示します。

コンストラクタ
  new Slide(div,times);
    div   : 操作対象のレイア
    times : 表示に使用するフレーム数

スライド動作登録メソッド
  - スライドオブジェクトの表示方法を設定します。
  registerAction(action)
    action : 動作の種類

           クリップのみ
             Slide.LEFT_TO_RIGHT             : 左->右
             Slide.TOP_TO_BOTTOM             : 上->下
             Slide.RIGHT_TO_LEFT             : 右->左
             Slide.BOTTOM_TO_TOP             : 下->上
             Slide.CENTER_TO_LEFTRIGHT       : 中央->左右
             Slide.CENTER_TO_TOPBOTTOM       : 中央->上下
             Slide.LEFTTOP_TO_RIGHTBOTTOM    : 左上->右下
             Slide.RIGHTTOP_TO_LEFTBOTTOM    : 右上->左下
             Slide.RIGHTBOTTOM_TO_LEFTTOP    : 右下->左上
             Slide.LEFTBOTTOM_TO_RIGHTTOP    : 左下->右上
             Slide.CENTER_TO_ROUND           : 中央->周囲

           クリップとスライド
             Slide.LEFT_TO_RIGHT_IN          : 左->右
             Slide.TOP_TO_BOTTOM_IN          : 上->下
             Slide.RIGHT_TO_LEFT_IN          : 右->左
             Slide.BOTTOM_TO_TOP_IN          : 下->上
             Slide.LEFTTOP_TO_RIGHTBOTTOM_IN : 左上->右下
             Slide.RIGHTTOP_TO_LEFTBOTTOM_IN : 右上->左下
             Slide.RIGHTBOTTOM_TO_LEFTTOP_IN : 右下->左上
             Slide.LEFTBOTTOM_TO_RIGHTTOP_IN : 左下->右上

通知関数登録メソッド
  - 実行動作時に呼び出す関数を登録します
  registerCallback(k,func,data)
    k    : 登録する種類
           Slide.ACTIONCALLBACK : 実行通知
           Slide.ENDCALLBACK    : 終了通知

    func : 登録する関数
           func は以下の形式で呼び出されます
             func( slide, clientData );
               slide      : 呼び出し元の Slide オブジェクト
               clientData : 登録時に指定した data

    data : func 呼び出し時のデータ

動作初期化メソッド
  - Slide オブジェクト実行時の動作方向を設定します
  initAction(dir);
    dir : 表示方向
          true  : 順方向( 表示方向 )
          false : 逆方向( 消去方向 )

実行メソッド
  - 1フレーム分だけ表示を更新します
  bool = doAction()
    bool : 実行結果
           true  : 動作完了
           false : 動作未完

使い方

デモ用のサンプルでは多少スクリプトが複雑になるので、 単純化した下のスクリプトで説明しましょう。

サンプル
サンプル
<style type="text/css"><!--
/* ===== スライドのスタイル定義 ===== */
.slide { position:absolute; visibility:hidden; }
#slide1{
  left:50; top:100;
  width:250; height:100; clip:rect(0 250 100 0);
  text-align:center;
  font-size:24pt; font-weight:bold; color:#ffffee;
  background-color:#339966; layer-background-color:#339966;
}
--></style>
<script language="JavaScript"><!--
// 旧バージョン用ダミー関数
function init      (){}
function closure   (){}
function showSample(){}
function hideSample(){}
// --></script>
<script language="JavaScript1.2"><!--
// ===== スライドサンプル =====
sampleFrames   = 10;   // 表示フレーム数
sampleInterval = 100;  // 表示間隔( msec )
sampleTid      = null; // タイマ識別子
sampleSlide    = null; // 選択されたスライド

// Slide オブジェクトの生成
function init(){
  var div=initDivPos(getDivFromName('slide1'));
  sampleSlide = new Slide(div,sampleFrames);
  sampleSlide.registerAction(Slide.LEFT_TO_RIGHT);
}
// 取消処理
function closure(){
  if(sampleTid){ clearTimeout(sampleTid); sampleTid=null; }
}
// スライド表示処理
function showSample(){
  closure();
  sampleSlide.initAction(true);
  doSample();
}
// スライド消去処理
function hideSample(){
  closure();
  sampleSlide.initAction(false);
  doSample();
}
// スライド実行処理
function doSample(){
  sampleTid = sampleSlide.doAction()?
                null:setTimeout('doSample()',sampleInterval);
}
// --></script>
</head>
<body ... onLoade="init();" onUnload="closure();">
    :
<form>
<input type="button" value="表示する" onClick="showSample();">
<input type="button" value="消す"     onClick="hideSample();">
</form>
<div class="slide" id="slide1">サンプル</div>
    :

例によって、この文字の部分は 「ライブラリ集」で紹介している関数です。

また、この文字の部分はこのサンプル特有の部分です。

スライドさせるレイアは absolute なレイアで、表示完了時の位置に配置します。

スライド動作の設定は初期表示時( onLoad - init関数 )に Slide オブジェクトを生成し、 もし、その動作が変化しないのなら一緒に動作も定義( registerAction )します。

表示や消去開始時( showSample, hideSample )には動作させる Slide オブジェクトの 初期化( initAction )をしてから動作( doAction )させます。

また、この例では何もしていませんが、デモ用スクリプトのように動作中に別の動作を 行いたい場合は registerCallback 関数を使用して連動する動作も定義できます。


注意事項


Copyright(c) 1998 - 2001 ShinSoft. All rights reserved.