JSFiddle - React, Tailwind, and code Playground

by arcm111

HTML

<div id='wrap'>
    <div id='mask'>
        <div id='cont'>
        </div>
    </div>
    <div id='sbc'>
        <div id='sb'>
        </div>
    </div>
</div>

CSS

#wrap {
    width: 200px;
    height: 400px;
    border: 1px solid black;
}

#mask {
    width: 180px;
    height: 400px;
    overflow: hidden;
    float: left;
    position: absolute;
}

#cont {
    width: 180px;
    position: absolute;
    background: #222;
}

#sbc {
    width: 20px;
    height: 400px;
    float: right;
    position: relative;
    background: #444;
}

#sb {
    position: absolute;
    width: 20px;
    top: 10px;
    background: #666;
}
.item {
    width: 160px;
    margin: 5px 10px;
    height: 40px;
    background: #999;
    line-height: 40px;
    font-size: 24px;
    text-indent: 20px;
    color: #333;
}

JavaScript

var cont = document.getElementById('cont');
var parent = document.getElementById('sbc');
var elm = document.getElementById('sb');

for(var i = 0; i < 40; i++)
{
    var item = document.createElement('div');
    item.className = 'item';
    item.innerText = i.toString();
    cont.appendChild(item);
}

var enableScroll = function(elm, parent, cont)
{
    var pos, ph = parent.offsetHeight, ch = cont.offsetHeight, elmY, contY;
    var scale = ch / (ph - 20);
    var bh = ph / scale;
    elm.style.height = bh + 'px';
    console.log(ph, bh, ch, scale);
    var onMove = function()
    {
        var e = event || window.event, dist = e.pageY - pos;
        if(elmY + dist < 10)
        {
            elm.style.top = '10px';
            cont.style.top = 0;
        }
        else if(elmY + dist + bh > ph - 10)
        {
            elm.style.top = ph - bh - 10 + 'px';
            cont.style.top = ph - ch + 'px';
        }
        else
        {
            elm.style.top = elmY + dist + 'px';
            cont.style.top =  contY - scale * dist + 'px';
        }
    };
    
    var onUp = function()
    {
        document.removeEventListener('mousemove', onMove, false);
        document.removeEventListener('mouseup', onUp, false);
    };
    
    elm.onmousedown = function(event)
    {
        var e = event, y = e.pageY;
        e.preventDefault();
        pos = y;
        elmY = elm.offsetTop;
        contY = cont.offsetTop;
        document.addEventListener('mousemove', onMove, false);
        document.addEventListener('mouseup', onUp, false);
    };
    
    var onWheel = function(event){
        event.preventDefault();
        var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail) ));
        var ct = cont.offsetTop, et = elm.offsetTop, dist = delta * -20 / scale;
        console.log(dist, delta);
        if(et + dist < 10)
        {
            elm.style.top = '10px';
            cont.style.top = 0;
        }
        else if(et + dist + bh > ph - 10)
    ...