DEMO

こんな感じのスクリプト書いて、idの「box」「barbox」「bar」を動かしてます。
ただこれまだ機能的に抜けがあるし、もっとスマートなやり方あるんだろうなー
まあ練習にはなったけど。改善点だれか指摘してくれたら嬉しい。


//////////////////グローバル変数////////////////////
//// バーを動かすonmouseMoveのスイッチ用。onmouseClickでtrueにしてる ////
var dragFlag=false;
//// onmouseMoveで使ってるマウス座標格納変数 ////
var blockY;
//// バー関係を入れる変数 ////
var nbar;
//// xにはバーとコンテンツボックスを結ぶ共通値(%)が入る。 /////
var x=0;
//// mouseWhile、スクロールのとこのループで使う変数 ////
var i=0;
//コンテンツボックスの高さ初期値入れる変数。
var a=0;


//■■■■初期読み込みfunction■■■■//
onload=function(){
//////こっからもろもろの設定値//////
//aにスクロール時の、コンテンツボックスの基準値の高さに使う//
a=box.offsetTop;

//////バー関係//////
//barboxのステータス。
var barbox=document.getElementById("barbox");
//barのステータス。
var nbar=document.getElementById("bar");
//バーの高さ。「ブラウザの高さ÷コンテンツボックスのheight×100」の式で出したパーセントをCSSに入れる//
nbar.style.height=(document.documentElement.clientHeight/box.clientHeight)*100+"%";

//コンテンツボックスの移動範囲を制御するために必要な値を出している。
//「コンテンツボックスのheight+コンテンツボックスの高さ+20-ブラウザの高さ」 +20はbottomの余白用
var ob=box.clientHeight+box.offsetTop+20-document.documentElement.clientHeight;


/////マウスボタンを押したときの処理/////
nbar.onmousedown=function(evt){
//onmousemoveのとこでバーの移動範囲制限に使うaに値を入れる。
a=evt.pageY-nbar.offsetTop;
dragFlag=true;//フラグオン
if(document.all&&!window.opera){
//ドラッグする要素上でクリック座標を取得(IE)
blockY=window.event.offsetY;
}else{
//ドラッグする要素上でのクリック座標を取得(IE以外)
blockY=evt.pageY-nbar.offsetTop;
}
return false
};


/////マウスポインタ移動時の処理/////
document.onmousemove=function(evt){
//ページのスクロール量を取得
scrollY=document.body.scrollTop||document.documentElement.scrollTop;

//dragFlagがtrueなら処理を。その後IEとそれ以外で処理を振り分ける。
if(dragFlag){
if(document.all&&!window.opera){
//ドラッグ処理(IE)マウス座標とaを使って、バーの動くYの範囲を制限するif。
if(window.event.clientY>=a&&a+barbox.clientHeight-nbar.clientHeight>=window.event.clientY){
nbar.style.marginTop=(window.event.clientY+scrollY-blockY-2)+"px";
}
}else{
//ドラッグ処理(IE以外)マウス座標とaを使って、バーの動くYの範囲を制限するif。
if(evt.pageY>=a&&a+barbox.clientHeight-nbar.clientHeight>=evt.pageY){
nbar.style.marginTop=(evt.pageY-blockY)+"px";
}
}

//バーの高さを数値化する。.splitを使ってpxを外さないと計算に使えない。
var mt=nbar.style.marginTop.split("px");

//共通値xに「バーの高さ÷(コンテンツボックスのheight-バーのheight)*100」で出したパーセントを入れる。
x=(mt[0]/(barbox.clientHeight-bar.clientHeight))*100;


//ボックスのmargin-topに「共通値x*コンテンツボックス値ob/-100」の式の値を入れる。
//マイナス100はバーと逆向きに動かすため。x/-100でパーセントに変換。それをobにかける。
document.getElementById("box").style.marginTop=(ob*x/-100)+"px";


}//DragFlag
return false
};


/////マウスボタンを離したときの処理/////
document.onmouseup=function(){
//スクロールfunctionに渡す用としてiにコンテンツボックスの高さを入れる
var topnum=document.getElementById("box").style.marginTop.split("px");
i=Number(topnum[0]);
dragFlag=false;
};

}
//■■■■初期読み込みfunction end■■■■//


//■■■■スクロールホイールfunction■■■■//
window.onmousewheel = function(e){
//ボックスコンテンツの移動範囲。ブラウザからはみ出た部分の距離の部分だけ移動。
var box=document.getElementById("box");
var ob=box.clientHeight+20-document.documentElement.clientHeight+a;
//topnumにボックスの高さの数値を入れます。
var topnum=box.style.marginTop.split("px");

//スクロールホイールの前後で移動量iを加減していく。
//xが移動範囲を越えたら数値の加減を逆転させて規制してる。が、ここ改良の余地あり。はみ出す。
if(e.wheelDelta>0){
i=i+8;
if(x<0){i=i-8;}
}else{
i=i-8;
if(x>100){i=i+8;}
}

//ここでiをコンテンツボックスのmargin-topに入れる。多分ここに入れるiの、mouseupからの受け渡しが上手くいってない。
box.style.marginTop=i+"px";


//xに「コンテンツボックスの高さ÷コンテンツボックスの移動量*-100」でパーセントを出す。
x=(i/ob)*-100;

//コンテンツボックスと連動して動くバーの位置を入れる部分。
//「(バーボックスのheight-バーのheight)*共通値x/100」でバーボックス内でバーが何%の位置にいるか出して入れる。
var barbox=document.getElementById("barbox");
document.getElementById("bar").style.marginTop=((barbox.clientHeight-bar.clientHeight)*x/100)+"px";
};
//■■■■スクロールホイールfunction end■■■■//