趣味は車輪の再発明♪

jQueryで超簡単に使えるスクロールバープラグイン



jQueryのプラグインとして、シンプルなスクロールバーを作りましたのでご紹介。

複数の領域を連動させてスクロールする場合などに便利です。 2つのDIVを入れ子にして、自動的に表示されるスクロールバーを利用していますから、見た目はブラウザに依存します。 デザイン的にはそっけないので、美しくデザインされたページには使いにくいと思いますが、デザイン的にそうそう凝らない業務用のWEBアプリなどでは十分かも。


サンプル

スクロールバーを色の指定に利用するためのサンプルです。

下の4つの水平スクロールバーがここでご紹介しているjquery.scrlbarプラグインで作成されています。 上から順に赤、緑、青、透明度。それぞれのつまみを動かすと上のボックスの背景色が変わります。

R:

G:

B:

A:

ボタンはおまけです。 つまみをスムースに動かす処理は、「javascriptで数値を指定時間内に(なるべく)滑らかに変化させる」を参照

サンプルソース

サンプルのHTMLコード

<div id="jQueryScrlbarSample1">
	<div id="colorSample"></div>
	<div style="float:left;width:20px;">R:</div>
	<div id="sbhR" style="float:left;"></div>
	<br clear="all"/>
	<div style="float:left;width:20px;">G:</div>
	<div id="sbhG" style="float:left;"></div>
	<br clear="all"/>
	<div style="float:left;width:20px;">B:</div>
	<div id="sbhB" style="float:left;"></div>
	<br clear="all"/>
	<div style="float:left;width:20px;">A:</div>
	<div id="sbhA" style="float:left;"></div>
	<br clear="all"/>
</div>

サンプルのjavascriptコード

$(function() {
  //水平スクロールバーのオプション
  var rgbopt = {
    dir:'h',
    width:650,
    minValue: 0,
    maxValue:255,
    pageLen:15
  };
  //スクロールバー生成
  $("#sbhR,#sbhG,#sbhB,#sbhA").scrlbar(rgbopt);
  //スクロール時のハンドラ設定。
  $("#sbhR").scroll(function(){setR($(this).scrlbarPos());});
  $("#sbhG").scroll(function(){setG($(this).scrlbarPos());});
  $("#sbhB").scroll(function(){setB($(this).scrlbarPos());});
  $("#sbhA").scroll(function(){setA($(this).scrlbarPos());});
  //初期位置を設定
  $("#sbhR,#sbhG,#sbhB").scrlbarPos(0);
  $("#sbhA").scrlbarPos(255);
  //easingを使って、自動的に動かす処理(おまけ)
  var t = 500;
  $("#btnAutoSlide").click(function() {
    $("#btnAutoSlide").attr("disabled", true);
    easing( 0,255,t,
      function(value){ $("#sbhR").scrlbarPos(value); },
      function() {
        easing( 255,0,t*3,
          function(value){$("#sbhR").scrlbarPos(value);});
      });
    easing( 0,255,t*2,
      function(value){ $("#sbhG").scrlbarPos(value);},
      function() {
        easing( 255,0,t*2,
          function(value){ $("#sbhG").scrlbarPos(value);});
      });
    easing( 0,255,t*3,
      function(value){ $("#sbhB").scrlbarPos(value);},
      function() {
        easing(255,0,t,
          function(value){ $("#sbhB").scrlbarPos(value);},
          function(){$("#btnAutoSlide").attr("disabled", false);});
      });
  });
});
//色の要素と設定関数
var r=0,g=0,b=0,a=0;
function setR(value) { r = Math.floor(value); applyColor(); }
function setG(value) { g = Math.floor(value); applyColor(); }
function setB(value) { b = Math.floor(value); applyColor(); }
function setA(value) { a = Math.floor(value); applyColor(); }
//色の更新
function applyColor() {
  var bgColorCode = "#" + hex(r) + hex(g) + hex(b);
  var colorCode = "#" + hex(255-r) + hex(255-g) + hex(255-b);
  $("#colorSample")
    .css('backgroundColor', bgColorCode)
    .css('opacity', Math.round(100*a/255)/100)
    .css('color', colorCode)
    .html(
      'background-color:' + bgColorCode + ';' +
      'opacity:' + (Math.round(100 * a / 255) / 100) + ';');
}
//値を2桁の16進数文字列に変換
function hex(v) {
  var s = v.toString(16);
  if(v < 16) {
    s = "0" + s;
  }
  return s;
}

プラグインの使い方

スクロールバーを生成する

水平スクロールバーの生成

DIV要素を定義して、jQueryのセレクタで選択してオプションを与えます。オプションの説明は以下のソースを参照してください。

スクロール量について、HTML的にはピクセル単位で指定しますが、このプラグインでは論理的な値の範囲を指定します。 例示した背景色サンプルでは各色の要素を0から255の範囲で変化させることができるわけです。

		<div id="myScrlbar"></div>
		<script type="text/javascript">
		$(function() {
			$("#myScrlbar").scrlbar({
				dir:'h',		//方向の指定
				width:650,		//画面上の幅。ピクセル単位。
			    minValue: 0,	//スクロールバーのつまみが左端の時の論理値
			    maxValue:255,	//スクロールバーのつまみが右端の時の論理値
			    pageLen:15,		//つまみの大きさを論理値で指定
			    value:0			//初期のつまみの位置を論理値で指定
			    });
		});
		</script>
	

垂直スクロールバーの生成

例示はしていませんが、縦のスクロールバーも作れます。オプションのdirを"v"にして、幅ではなく高さを指定します。

		<div id="myScrlbar"></div>
		<script type="text/javascript">
		$(function() {
			$("#myScrlbar").scrlbar({
				dir:'v',		//方向の指定
				height:650,		//画面上の高さ。ピクセル単位。
			    minValue: 0,	//スクロールバーのつまみが上端の時の論理値
			    maxValue:255,	//スクロールバーのつまみが下端の時の論理値
			    pageLen:15,		//つまみの大きさを論理値で指定
			    value:0			//初期のつまみの位置を論理値で指定
			    });
		});
		</script>
	

操作

スクロール位置の取得(論理位置)
	var pos = $("#myScrlbar").scrlbarPos();
	alert("スクロール位置(論理位置)=" + pos);
	
スクロール位置の設定(論理位置)
	//論理位置100へ
	$("#myScrlbar").scrlbarPos(100));
	
スクロールハンドラの設定

jQueryのscrollメソッドでハンドラを設定すればOK。当然複数の処理を登録できます。

	$("#myScrlbar").scroll(function() {
		var pos = $("#myScrlbar").scrlbarPos();
		console.info("スクロール位置(論理値)=" + pos);
	});
	

制限事項

  1. 対応しました(2012-10-10)⇒minValueがmaxValueより大きいと正しく動作しません(改善したい)
  2. モバイルでは使えないと思います。Windows7のIE9とFirefox 15.0.1 で動作確認済み。

プラグインのソースファイル jquery.scrlbar.js

/**
 * シンプルなスクロールバープラグイン。
 * K.Takami 2012-09-06(THU)
 */
jQuery(document).ready(function() {
  //=======================================================================
  //プラグインの定義
  //=======================================================================
  jQuery.fn.scrlbar = function(option) {
    return this.each(function() {
      //選択された全要素を元にスクロールバークラスを生成
            new jQuery.scrlbar( this , option);
        });
  }
  //=======================================================================
  //論理単位のスクロール量を取得・設定
  //=======================================================================
  jQuery.fn.scrlbarPos = function(pos) {
    if(pos != undefined) {
      //値を設定
      return this.scrlbarPxPos(this.scrlbarPosToPx(pos));
    }
    //値を取得
    return this.scrlbarPxToPos(this.scrlbarPxPos());
  }
  //=======================================================================
  //ピクセル単位のスクロール量を取得・設定
  //=======================================================================
  jQuery.fn.scrlbarPxPos = function(px) {
    if(px != undefined) {
      //値を設定
      return this.each(function(){
        var sb = $(this);
        switch(sb.attr('dir')) {
          case 'h': sb.scrollLeft(px); break;
          case 'v': sb.scrollTop(px); break;
        }
      });
    }
    //値を取得
    switch(this.attr('dir')) {
      case 'h': px = this.scrollLeft(); break;
      case 'v': px = this.scrollTop(); break;
    }
    return px;
  }
  jQuery.fn.scrlbarViewport = function(pxViewportLen) {
    if(pxViewportLen != undefined) {
      return this.each(function(){
        var sb = $(this);
        switch(sb.attr('dir')) {
        case "h": sb.css('width', pxViewportLen + 'px'); break;
        case "v": sb.css('height', pxViewportLen + 'px'); break;
        }
        //sb.attr('pxViewportLen', pxViewportLen);
      });
    } else {
      pxViewportLen = $(this.get(0)).attr('pxViewportLen');
    }
    return pxViewportLen;
  }
  //=======================================================================
  //ピクセル単位から論理単位への変換
  //=======================================================================
  jQuery.fn.scrlbarPxToPos = function(px) {
    var pageLen = this.attr('pageLen');
    var minValue = parseInt(this.attr('minValue'));
    var maxValue = parseInt(this.attr('maxValue'));
    var pxViewportLen = this.attr('pxViewportLen');
    var pos = 0;
    if(maxValue < minValue) {
      var valueLen = minValue - maxValue;
      var pxContentLen = Math.floor(pxViewportLen * valueLen / pageLen);
      pos = Math.floor(minValue - valueLen * px / pxContentLen);
    } else {
      var valueLen = maxValue - minValue;
      var pxContentLen = Math.floor(pxViewportLen * valueLen / pageLen);
      pos = Math.floor(minValue + valueLen * px / pxContentLen);
    }
    return pos;
  },
  //=======================================================================
  //論理単位からピクセル単位への変換
  //=======================================================================
  jQuery.fn.scrlbarPosToPx = function(pos) {
    var pageLen = this.attr('pageLen');
    var minValue = parseInt(this.attr('minValue'));
    var maxValue = parseInt(this.attr('maxValue'));
    var pxViewportLen = this.attr('pxViewportLen');
    var px;
    if(maxValue < minValue) {
      var valueLen = minValue - maxValue;
      var pxContentLen = Math.floor(pxViewportLen * valueLen / pageLen);
      px = Math.floor(pxContentLen * ((minValue - pos) / valueLen));
    } else {
      var valueLen = maxValue - minValue;
      var pxContentLen = Math.floor(pxViewportLen * valueLen / pageLen);
      px = Math.floor(pxContentLen * ((pos - minValue) / valueLen));
    }
    return px;
  }
  //=======================================================================
  //スクロールバークラス
  //=======================================================================
  jQuery.scrlbar = function(element, option) {
    //===================================================================
    //オプションの既定値を設定
    //===================================================================
    option = jQuery.extend({
      dir:"h",  //スクロールバーの方向を指定
              //"h":水平スクロールバー、"v":垂直スクロールバー
      minValue:0,  //つまみの論理下限値
      maxValue:100, //つまみの論理上限値
      pageLen:10  //論理ページ長(つまみの大きさに関連する)
    }, option);
    //二次的な既定値を設定
    option = jQuery.extend({
      value:option.minValue  //つまみの論理位置(デフォルトは下限値)
    }, option);
    //===================================================================
    //
    //スクロールバーは入れ子にした二つのDIV。
    //外側のDIVより内側の方が大きいと自動的にスクロールバーが表示されることを利用。
    //
    //===================================================================
    //===================================================================
    //外側のDIVの設定。念のためクラスを設定する
    //===================================================================
    var jqobj = jQuery(element);
    jqobj.addClass('scrlbar').addClass('scrlFrame');
    jqobj.css('overflow', 'scroll')
    //===================================================================
    //外側のDIVのスタイル設定。水平か垂直かで指定する項目が違う。
    //===================================================================
    var pxViewportLen = 0;
    switch(option.dir) {
    case "h"://水平スクロールバー
      //===============================================================
      //外側DIVの幅をオプションから取り出す
      //===============================================================
      option = jQuery.extend({ width:100 }, option);
      pxViewportLen = option.width;
      //===============================================================
      //外側DIVのスタイル指定
      //===============================================================
      jqobj
        .css('width', pxViewportLen + 'px')  //幅
        .css('height', '20px')   //高さ(固定)
        .css('overflow-x', 'scroll') //IE用:水平方向へスクロールする
        .css('overflow-y', 'hidden'); //IE用:垂直方向へスクロールしない
                        //(垂直方向の矢印ボタンを表示させない)
      break;
    case "v"://垂直スクロールバー
      //===============================================================
      //外側DIVの高さをオプションから取り出す
      //===============================================================
      height = jQuery.extend({ height:100 }, option);
      pxViewportLen = option.height;
      //===============================================================
      //外側DIVのスタイル指定
      //===============================================================
      jqobj
        .css('width', '20px')   //幅(固定)
        .css('height', pxViewportLen + 'px') //高さ
        .css('overflow-x', 'hidden') //IE用:水平方向へスクロールしない
                        //(垂直方向の矢印ボタンを表示させない)
        .css('overflow-y', 'scroll'); //IE用:垂直方向へスクロールする
      break;
    }
    jqobj
    .attr('dir', option.dir)
    .attr('minValue', option.minValue)
    .attr('maxValue', option.maxValue)
    .attr('pageLen', option.pageLen)
    .attr('pxViewportLen', pxViewportLen)
    //===================================================================
    //内部のDIVを生成してクラスを設定
    //===================================================================
    var scrlContent = jQuery('<div/>').addClass('scrlContent');
    //===================================================================
    //内側DIVの論理的大きさを計算
    //===================================================================
    var valueLen = 0;
    if(option.maxValue < option.minValue) {
      valueLen = option.minValue - option.maxValue;
    } else {
      valueLen = option.maxValue - option.minValue;
    }
    var wholeLen = valueLen + option.pageLen;
    //===================================================================
    //内側DIVのピクセル単位の大きさを計算
    //===================================================================
    var pxRange = Math.floor(
        pxViewportLen * (wholeLen / option.pageLen));
    //===================================================================
    //内側DIVのサイズを設定
    //===================================================================
    switch(option.dir) {
    case "h"://水平スクロールバー
      scrlContent.css('width', pxRange + 'px').css('height', '20px');
      break;
    case "v"://垂直スクロールバー
      scrlContent.css('width', '20px').css('height', pxRange + 'px');
      break;
    }
    //===================================================================
    //内側DIVを外側DIVの内部に追加
    //===================================================================
    jqobj.empty().append(scrlContent);
  };
});

バックリンクフォロー

  1. チャットトップページ / jQueryで超簡単に使えるスクロールバープラグイン


RSS Feed Widget
jQueryで超簡単に使えるスクロールバープラグイン
(http://bicycle.life.coocan.jp/takamints/index.php/techtips/jqueryScrlbar)
by Koji Takami ( email: vzg03566@gmail.com, GitHub: takamin )