SoFunction
Updated on 2025-04-14

Simulating Apple-style scrollbars with JTrackBar


function JObj(){}
JObj.$c = function(tag){return (tag)};
JObj.$ = function(id){return (id)};
 = function(pRateString){
    if(!isNaN(pRateString)) return false;
    if((-1,1) != "%")
        return false;
    if(isNaN((0, - 1)))
        return false;
    return true;
}

function JPos(){}
 = function(pTarget){
    var x_ = y_ = 0;
    while(){
            x_ += ;
            y_ += ;
            pTarget = ;
    }
    x_ += ;
    y_ += ;
    return {x:x_,y:y_};
}

 = function(evt){
    var x_ = y_ = 0;
    evt = evt || ;
    if( || ){
        x_ = ;
        y_ = ;
    }else{
        x_ =  +  - ;
        y_ =  +  - ;
    }

    return {x:x_,y:y_};        
}



<!--
/*
----------------------------------------------------------------------
JTrackBar
Initial date: 2007/07/11
Author:xlingFairy
Blog:

Currently, only horizontal and vertical ones have not been written.
Design functions:
When changed, the event onChange is triggered and the current value is passed.

2007/07/12
Added drag function.

2007/07/13
Add skin function

2007/08/06
Add vertical. And fix a bug caused by setRange.

Not made function: specify trackFrequence, you can try to modify it yourself.

Please respect the fruits of labor! The original work information is not allowed! You will bear the consequences at your own risk!
----------------------------------------------------------------------
*/
function JPos(){

}

 = function(pTarget){
    var _x = 0;
    var _y = 0;
    while(){
            _x += ;
            _y += ;
            pTarget = ;
    }
    _x += ;
    _y += ;

    return {x:_x,y:_y};
}

 = function(evt){
    var _x,_y;
    evt = evt || ;
    if( || ){
        _x = ;
        _y = ;
    }else{
        _x =  +  - ;
        _y =  +  - ;
    }
    return {x:_x,y:_y};
}

function JTrackBar(pParent){
    var self = this;

    var $ = function(pId){
        return (pId);
    }

    var $c = function(pTag){
        return (pTag);
    }

    var trackBarType;    //V & H
    if((typeof pParent).toUpperCase() == "OBJECT")
        var body = pParent;
    else
        var body = $(pParent) || ;
    var oOutline    = null;
    var oTrackArea     = null;
    var oBtnPointer    = null;
    var oArrBtnLeft = oArrBtnRight = oArrBtnUp = oArrBtnDown = null;

    var inDrag         = false;
    var dragStartPos = null;

var maxPosition    = 100;    //Maximum scale
var minPosition        = 0;    //Minimum scale
    var base            = 0;
var position        = 0;    //Current location
var trackFrequence    = 10;    //How many ticks can be moved once

    var defaultArrowW = defaultArrowH = 15;//Only for IE!

     = function(pMin,pMax){
        maxPosition = (pMin,pMax);
        minPosition    = (pMin,pMax);

        maxPosition -= minPosition;
        base = minPosition;
        minPosition = 0;
    }    

    var outlineWidth,trackAreaWidth,preFrequenceWidth;
    var outlineHeight,trackAreaHeight,preFrequenceHeight;

     = new Function();

    var getRunStyle = function(pObj,pProperty){
        try{
            if()
            return eval("." + pProperty);
        else
            return (pObj,"").getPropertyValue(pProperty);
        }catch(e){
            alert(e);
        }
    }

    /*-----------------------------------------------------*/
    var createOutline = function(pWH){
        oOutline            = $c("DIV");
        (oOutline);
            = "JTrackBarStand";
        if(trackBarType == "H")
             = pWH + "px";
        else if(trackBarType == "V")
             = pWH + "px";
         = "hidden";
    }
    /*-----------------------------------------------------*/
    var createArrBtn    = function(pDirection){
        var arrBtn = $c("DIV");
        switch(pDirection){
            case "LEFT":
                 = "btnLeft";
                 = "left";
                    = "left";
                break;
            case "RIGHT":
                 = "btnRight";
                 = "left";
                    = "left";        
                break;
            case "UP":
                 = "btnUp";
                break;
            case "DOWN":
                 = "btnDown";
                break;
        }

         = pDirection;
         = arrBtn_click;
        return arrBtn;
    }

    var arrBtn_click = function(evt){

        evt =  || evt;
        var o =  || ;

        switch(){
            case "LEFT":
            case "UP":
                ( -trackFrequence);
                break;
            case "RIGHT":
            case "DOWN":
                (trackFrequence);
                break;
        }
    }

    var trackarea_click = function(evt){
        evt =  || evt;
        var mPos = (evt);

        var pos_ = (oTrackArea);

        if(trackBarType == "H"){
            var w_ = parseInt(getRunStyle(oBtnPointer,"width"));        
            (parseInt(( - pos_.x) / preFrequenceWidth));
        }else{
            var h_ = parseInt(getRunStyle(oBtnPointer,"height"));
            (parseInt(( - pos_.y) / preFrequenceHeight));
        }
    }

    var createHTrackArea = function(){
        var w_ = parseInt(getRunStyle(oArrBtnLeft,"width"));
        if(isNaN(w_)) w_ = defaultArrowW;

        trackAreaWidth = outlineWidth - 2 * w_;
        preFrequenceWidth = trackAreaWidth / (maxPosition - minPosition);

        oTrackArea = $c("DIV");
        (oTrackArea);

         = trackarea_click;

         = "trackAreaH";
         = trackAreaWidth + "px";
         = "left";
            = "left";
    }

    var createVTrackArea = function(){
        var h_ = parseInt(getRunStyle(oArrBtnUp,"height"));    
        if(isNaN(h_)) h_ = defaultArrowH;
        trackAreaHeight = outlineHeight - 2 * h_;
        preFrequenceHeight = trackAreaHeight / (maxPosition - minPosition);

        oTrackArea = $c("DIV");        
        (oTrackArea);

         = trackarea_click;
         = "trackAreaV";
         = trackAreaHeight + "px";
    }

    var recalcTrackArea = function(){
        if(trackBarType == "H"){
            var w_ = parseInt(getRunStyle(oArrBtnLeft,"width"));
            if(isNaN(w_)) w_ = defaultArrowW;

            trackAreaWidth = outlineWidth - 2 * w_;    
            preFrequenceWidth = trackAreaWidth / maxPosition;

             = trackAreaWidth + "px";
        }else{
            var h_ = parseInt(getRunStyle(oArrBtnUp,"height"));
            if(isNaN(h_)) h_ = defaultArrowH;

            trackAreaHeight = outlineHeight - 2 * h_;
            preFrequenceHeight = trackAreaHeight / maxPosition;
             = trackAreaHeight + "px";
        }
    }

    var pointer_mousedown = function(evt){
        inDrag = true;
        dragStartPos = (evt);
         = pointer_mousemove;
         = pointer_mouseup;
         = pointer_mouseout;
    }

    var pointer_mousemove = function(evt){
        if(!inDrag)    return;        
        var mPos = (evt);
        var pos_ = (oTrackArea);

        if(trackBarType == "H")
            (parseInt(( - pos_.x) / preFrequenceWidth));
        else
            (parseInt(( - pos_.y) / preFrequenceHeight));
    }

    var pointer_mouseup = function(){
        inDrag = false;
    }

    var pointer_mouseout = function(){
        //inDrag = false;
    }

    var createHPointer = function(){
        oBtnPointer = $c("DIV");
        (oBtnPointer);
         = pointer_mousedown;

         = "btnPointerH";
         = "absolute";

        var w_ = parseInt(getRunStyle(oBtnPointer,"width"));
        if(isNaN(w_)) w_ = defaultArrowW;

        var pos_ = (oTrackArea);
         = pos_.x - w_/2 + "px";
         = pos_.y + "px";
         += "left:" + (pos_.x - w_/2) + "px;top:" + pos_.y + "px;";
    }

    var createVPointer = function(){
        oBtnPointer = $c("DIV");    
        (oBtnPointer);
         = pointer_mousedown;

         = "btnPointerV";
         = "absolute";
        var h_ = parseInt(getRunStyle(oBtnPointer,"height"));
        if(isNaN(h_)) h_ = defaultArrowH;

        var pos_ = (oTrackArea);
         = pos_.y - h_/2 + "px";
         = pos_.x + "px";
         += "left:" + pos_.x + "px;top:" + (pos_.y - h_/2) + "px";
    }

    /*-----------------------------------------------------*/
     = function(pWidth){
        trackBarType = "H";
        outlineWidth = pWidth;
        createOutline(pWidth);

        oArrBtnLeft = createArrBtn("LEFT");
        (oArrBtnLeft);

        createHTrackArea();

        oArrBtnRight = createArrBtn("RIGHT");
        (oArrBtnRight);

        createHPointer();
    }
    /*-----------------------------------------------------*/
     = function(pHeight){
        trackBarType = "V";
        outlineHeight = pHeight;
        createOutline(pHeight);

        oArrBtnUp = createArrBtn("UP");
        (oArrBtnUp);

        createVTrackArea();

        oArrBtnDown = createArrBtn("DOWN");
        (oArrBtnDown);

        createVPointer();
    }    
    /*-----------------------------------------------------*/    

     = function(pPosition){
        position += pPosition;
        (position);
    }

     = function(pPosition){
        position = pPosition;
        if(position > maxPosition)
            position = maxPosition;
        if(position < minPosition)
            position = minPosition;        

        var pos_ = (oTrackArea);

        if(trackBarType == "H"){
            var w_ = parseInt(getRunStyle(oBtnPointer,"width"));
            if(isNaN(w_)) w_ = defaultArrowW;

             = pos_.x - w_/2 + preFrequenceWidth * position  + "px"; 
        }else if(trackBarType == "V"){
            var h_ = parseInt(getRunStyle(oBtnPointer,"height"));
            if(isNaN(h_)) h_ = defaultArrowH;
             = pos_.y - h_/2 + preFrequenceHeight * position  + "px"; 
        }

        doChange();
    }

    var doChange = function(){
        (position + base);
    }

     = function(){
        return position;
    }

     = function(pSkin){
         = pSkin;
        recalcTrackArea();
        (minPosition)
    }
}



function JScroll(pWidth,pHeight,pBody){
    var self        = this;
    var oOutline    = null;
    var oContentArea = null;
    var oTrackBarArea = null;

     = null;

    var w        = (pWidth) ? pWidth : (!isNaN(pWidth) ? pWidth + "px" : "100%");
    var h        = (pHeight) ? pHeight : (!isNaN(pHeight) ? pHeight + "px" : "100%");

    var db_ = JObj.$(pBody) || ;

    var createOutline = function(){
        oOutline = JObj.$c("DIV");
         = "oOutline";
        db_.appendChild(oOutline);
        with(){
            width     =    w;
            height    =    h;
            overflow = "hidden";
        }

        oContentArea = JObj.$c("DIV");
        (oContentArea);
         = "oContentArea";
        with(){
            width =  - 25 + "px";
            height =  + "px";
            styleFloat = "left";
            cssFloat = "left";
        }
    }

     = function(){
        createOutline();
    }

    var createTrackBar = function(){
        oTrackBarArea = JObj.$c("DIV");
        (oTrackBarArea);
        with(){
            width = 20 + "px";
            height = ;
            stylefloat = "left";
            cssFloat    = "left";
            overflow     = "hidden";
        }
         = new JTrackBar(oTrackBarArea);
         = function(pTrackPosition){
             = pTrackPosition;
        }                

        (0,);
        ();
        ("JTrackBarSky");
    }    

     = function(pId){
        (JObj.$(pId));
         = "hidden";

        createTrackBar();
    }

     = function(pSkin){
        (pSkin)
    }
}