Cross Browser のための DHTML


・スライダオブジェクト

数値などを直感的に入力できるものとしてスライダがあります。 スライダは直接文字列を入力しないので、 文字種や入力値の範囲などのチェックが不要になる利点もあります。

そこで、「汎用イベントハンドラ」を使用したスライダオブジェクトを紹介しましょう。

値:

上のサンプルは、2つの横スライダと1つの縦スライダで、 それぞれ 0 〜 100、 0 〜 -100、-100 〜 100 の範囲の数値を示すことができます。

スライダの操作は両端の矢印ボタンを操作すれば 5づつ増減し、 スライダをドラッグ操作すれば 0.5 または 1 単位の精度で値を設定することができます。

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

<script language="JavaScript1.2"><!--
// Slider オブジェクト( 関数 )
function Slider(div,dir,len,min,max,pos,
                    stcb,stcd,mvcb,mvcd,edcb,edcd){
  var ctrl=ech_attachMouseDrag(div,
             slideStart,null, slideMove,null, slideEnd,null,
             null,null);
  var x=getDivLeft(div), y=getDivTop(div);
  ctrl.dir = dir; ctrl.len = len;
  ctrl.min = min; ctrl.max = max;
  if(dir==0){   // horizontal
    ctrl.minX = x-Math.abs((pos-min)*len/(max-min));
    ctrl.maxX = x+Math.abs((max-pos)*len/(max-min));
    ctrl.minY = y; ctrl.maxY = y;
  } else {      // vertical
    ctrl.minX = x; ctrl.maxX = x;
    ctrl.minY = y-Math.abs((pos-min)*len/(max-min));
    ctrl.maxY = y+Math.abs((max-pos)*len/(max-min));
  }
  ctrl.slideStartCB=stcb; ctrl.slideStartCD=stcd;
  ctrl.slideMoveCB =mvcb; ctrl.slideMoveCD =mvcd;
  ctrl.slideEndCB  =edcb; ctrl.slideEndCD  =edcd;
  ctrl.getPos      = getSliderPos;
  ctrl.slideTo     = slideTo;
  ctrl.slideBy     = slideBy;
  return ctrl;
}
// 現在位置取り出しメソッド
function getSliderPos(){
  return this.dir==0?
    ((getDivLeft(this.div)-this.minX)*(this.max-this.min)
     /this.len+this.min
    ):
    ((getDivTop (this.div)-this.minY)*(this.max-this.min)
     /this.len+this.min
    );
}
// 位置変更メソッド( 絶対値 )
function slideTo(pos,norep){
  if(this.max>this.min){
    if(pos>this.max) pos=this.max;
    if(pos<this.min) pos=this.min;
  }
  else {
    if(pos>this.min) pos=this.min;
    if(pos<this.max) pos=this.max;
  }
  var x=(this.maxX-this.minX)*(pos-this.min)
       /(this.max-this.min)+this.minX;
  var y=(this.maxY-this.minY)*(pos-this.min)
       /(this.max-this.min)+this.minY;
  if(x<this.minX) x=this.minX;
  if(x>this.maxX) x=this.maxX;
  if(y<this.minY) y=this.minY;
  if(y>this.maxY) y=this.maxY;
  if(x!=getDivLeft(this.div)||y!=getDivTop(this.div)){
    moveDivTo(this.div,x,y);
    if((arguments<2 || !norep) && this.slideMoveCB)
      this.slideMoveCB(this,this.slideMoveCD,pos);
  }
}
// 位置変更メソッド( 相対値 )
function slideBy(pos,norep){
  this.slideTo(this.getPos()+pos,norep);
}
// ハンドラ( ドラッグ開始 )
function slideStart(ctrl,client){
  if(ctrl.slideStartCB)
    ctrl.slideStartCB(ctrl,
           ctrl.slideStartCD,ctrl.getPos());
}
// ハンドラ( ドラッグ )
function slideMove(ctrl,client){
  var x=ox=getDivLeft(ctrl.div), y=oy=getDivTop(ctrl.div);
  switch(ctrl.dir){
  case 0:          // horizontal
    if(ctrl.pageX>ctrl.maxX)      x=ctrl.maxX;
    else if(ctrl.pageX<ctrl.minX) x=ctrl.minX;
    else {
      x+=ctrl.pageX-ctrl.curX;
      if(x<ctrl.minX) x=ctrl.minX;
      if(x>ctrl.maxX) x=ctrl.maxX;
    }
    break;
  case 1:          // vertical
    if(ctrl.pageY>ctrl.maxY)      y=ctrl.maxY;
    else if(ctrl.pageY<ctrl.minY) y=ctrl.minY;
    else {
      y+=ctrl.pageY-ctrl.curY;
      if(y<ctrl.minY) y=ctrl.minY;
      if(y>ctrl.maxY) y=ctrl.maxY;
    }
    break;
  }
  if(ox!=x||oy!=y){
    moveDivTo(ctrl.div,x,y);
    if(ctrl.slideMoveCB)
      ctrl.slideMoveCB(ctrl,
             ctrl.slideMoveCD,ctrl.getPos());
  }
}
// ハンドラ( ドラッグ終了 )
function slideEnd(ctrl,client){
  if(ctrl.slideEndCB)
    ctrl.slideEndCB(ctrl,ctrl.slideEndCD,ctrl.getPos());
}
// --></script>

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

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

登録関数
  スライダオブジェクト生成関数
    - スライダオブジェクト用イベント制御オブジェクトを生成します
    object = Slider(div,dir,len,min,max,pos,
                        stcb,stcd, mvcb,mvcd, edcb,edcd);
      div       : スライド操作を行うレイアオブジェクト
      dir       : 方向  0 = 水平方向, 1 = 垂直方向
      len       : スライド操作可能な部分の長さ( pixel )
      min, max  : 取りうる値の最小値と最大値
           注) スライダが最左端及び最右端( dir=0 )または
               最上端及び最下端( dir=1 )にある場合の値
      pos       : 現在の div の位置での値
      stcb,stcd : 操作開始時に呼び出す関数(stcb)と引数(stcd)
                  不要な場合は null を指定する

                  関数の呼出し形式は以下の通り
                  stcb(ctrl,stcd,pos);
                    ctrl : イベント制御オブジェクト
                    stcd : ユーザ定義変数
                    pos  : 現在の値( min 〜 max の値 )

      mvcb,mvcd : 操作中に呼び出す関数(mvcb)と引数(mvcd)
                  不要な場合は null を指定する

                  関数の呼出し形式は以下の通り
                  mvcb(ctrl,mvcd,pos);
                    ctrl : イベント制御オブジェクト
                    mvcd : ユーザ定義変数
                    pos  : 新しい値( min 〜 max の値 )

      edcb,edcd : 操作完了時に呼び出す関数(edcb)と引数(edcd)
                  不要な場合は null を指定する

                  関数の呼出し形式は以下の通り
                  edcb(ctrl,edcd,pos);
                    ctrl : イベント制御オブジェクト
                    edcd : ユーザ定義変数
                    pos  : 新しい値( min 〜 max の値 )

      object    : スライダ用イベント制御オブジェクト

イベント制御オブジェクト
  現在位置取り出しメソッド
    - 現在のスライダ位置から対応する数値に変換します
    pos = getPos();
      pos       : 現在値( min 〜 max の値 )

  位置変更メソッド( 絶対値 )
    - スライダを指定した値に対応する位置に移動します
    slideTo(pos[,norep]);
      pos       : 新しい値( min 〜 max の値 )
      norep     : 変更時の関数呼出ししない
                  false = 通知, true = 非通知

  位置変更メソッド( 相対値 )
    - スライダを現在位置から指定値に相当する位置だけ移動します
    slideBy(pos[,norep]);
      pos       : 変位
      norep     : 変更時の関数呼出ししない
                  false = 通知, true = 非通知

  イベント制御オブジェクトの公開プロパティ
    div : [C ] スライダとして登録したレイアのオブジェクト
    min : [C ] Slider 関数呼出し時の min
    max : [C ] Slider 関数呼出し時の max
    dir : [C ] Slider の方向

    [C ] は常に有効

イベント制御オブジェクトは「汎用イベントハンドラ」で紹介しているものに スライダ特有の機能を実装したものです。

#> 本来はイベント制御オブジェクトのサブクラスとして実装すべきなのですが、 IE ではサブクラスとしてオブジェクトを生成するための簡単な手法がないので このような実装になっています。


使い方

Slider オブジェクトはスライダ部分のレイアの移動管理と指定された範囲の数値を管理するのみなので、 スクロールバーのような形態にするには更に幾つかの要素を必要とします。

冒頭のサンプルでは1単位移動のためのボタン( 増&減ボタン )と スライド可能部分をはっきりさせる背景などです。

例えば、スライダ、増減ボタンのサイズが 10×10(pixel) で、移動範囲が 200pixel の 横方向のスライダを (100,200) の位置に配置させ、数値の範囲を 0 〜 100 とする場合は 以下のようにします。

<style type="text/css"><!--
/* 減ボタン */
#arrow1 { position:absolute;
  left:100; top:200;
  width:10; height:10; clip:rect(0 10 10 0);
}
/* スライダ */
#slider { position:absolute;
  left:110; top:200;
  width:10; height:10; clip:rect(0 10 10 0);
}
/* スライダの背景 */
#scrollbar { position:absolute;
  left:110; top:200;
  width:210; height:10; clip:rect(0 210 10 0);
  background-color:#e0e0e0; layer-background-color:#e0e0e0;
}
/* 増ボタン */
#arrow2 { position:absolute;
  left:320; top:200;
  width:10; height:10; clip:rect(0 10 10 0);
}
--></style>
<script language="JavaScript"><!--
slider=null;       // Slider オブジェクト

// 初期化
function init(){
  // Sliderオブジェクトの生成
  var div = initDivPos(getDivFromName('slider'));
  slider=Slider(div,0,200, 0,100,0,null,null,slide,2,null,null)
               .linkCtrl(getDivImage(div,'sldimg'));
}
// ドラッグ操作処理
function slide(ctrl,client,pos){
  // 設定値変更時の処理
}
// 増減ボタン操作処理
function arrow(val){
  if(slider) slider.slideBy(val);
}
// --></script>
    :
</head>
<body ... onLoad="init();">
    :
<div id="scrollbar"></div>
<div id="arrow1"><a href="javascript:void(0);"
     onClick="arrow(-1);"><img
     src="arrow1.gif" border=0 width=10 height=10
></a></div>
<div id="arrow2"><a href="javascript:void(0);"
     onClick="arrow(1);"><img
     src="arrow1.gif" border=0 width=10 height=10
></a></div>
<div id="slider><img
     name="sldimg" src="slider.gif" width=10 height=10
></div>

例によってこの文字の部分は「ライブラリ集」または 「汎用イベントハンドラ」で紹介している関数です。

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

増減ボタン、スクロールバーの各要素を absolute なレイアとして配置していますが、 スライダを除く部分全体を1つの画像としてクライアントサイドイメージマップを使用しても 実現できます。

増減ボタンの挙動を画像部分の onClick( arrow関数呼出 )により行っていますが、 mousedown, mouseup イベントを使用して押されている間一定周期で arrow関数を呼び出しても 良いでしょう。

また、この場合、mousedown, mouseup で画像を切り換えると、より効果的でしょう。

Sliderオブジェクトの生成に関しては、スライダとして登録するレイアを指定して Slider関数を呼び出すだけですが、もし、 このサンプルのようにレイア内に画像があるならイベント制御オブジェクトに画像を関連付けます。


注意事項


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