制作JavaScript自定义ScrollBar

时间:2013-02-27 13:41:12

标签: javascript

我说“JavaScript”。我正在尝试制作自己的JavaScript自定义滚动条。它几乎成功了。问题是我无法获得滚动速度的准确乘数。这是我的代码:

var elem = document.getElementById('scroll-area'),
    track = elem.children[1],
    thumb = track.children[0],
    height = parseInt(elem.offsetHeight, 10),
    cntHeight = parseInt(elem.children[0].offsetHeight, 10),
    trcHeight = parseInt(track.offsetHeight, 10),
    distance = cntHeight - height,
    mean = 50, // For multiplier (go faster or slower)
    current = 0;

elem.children[0].style.top = current + "px"; // Set default `top` value as `0` for initiation
thumb.style.height = Math.round(trcHeight * height / cntHeight) + 'px'; // Set the scrollbar thumb hight

var doScroll = function (e) {

    // cross-browser wheel delta
    e = window.event || e;
    var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));

    // (1 = scroll-up, -1 = scroll-down)
    // Always check the scroll distance, make sure that the scroll distance value will not
    // increased more than the content height and/or less than zero
    if ((delta == -1 && current * mean >= -distance) || (delta == 1 && current * mean < 0)) {
        current = current + delta;
    }

    // Move element up or down by updating the `top` value
    elem.children[0].style.top = (current * mean) + 'px';
    thumb.style.top = 0 - Math.round(trcHeight * (current * mean) / cntHeight) + 'px';

    e.preventDefault();

};

if (elem.addEventListener) {
    elem.addEventListener("mousewheel", doScroll, false);
    elem.addEventListener("DOMMouseScroll", doScroll, false);
} else {
    elem.attachEvent("onmousewheel", doScroll);
}

标记:

<div id="scroll-area">
    <div><!-- CONTENT --></div>
    <span class="scrollbar-track"><span class="scrollbar-thumb"></span></span>
</div>

我的问题出在mean = 50上。当您将容器滚动到内容的底部时,我在演示页面中创建的红线应该直接停在容器的底部,而不是高于该容器。

有人知道准确的结果吗?

PS:我还想添加一个功能,通过拖动滚动条拇指,用户可以滚动内容。但我想我首先要关注这个问题。谢谢你的帮助。

DEMO: http://jsfiddle.net/tovic/2B8Ye/

1 个答案:

答案 0 :(得分:2)

你可以更容易地做到这一点。 您可以设置其top属性而不是计算容器的scrollTop属性,而您猜测是什么 - 您不必检查内容是否高于0或低于高度,因为{{ 1}} property 不能设置为小于0或大于容器高度的值

Here's your modified fiddle

请注意,我必须使用其他scrollTop包装所有内容,以便滚动条不会与<div id="everything">...</div> div一起滚动。

此外,我假设#scroll-area div使用clientHeight代替offsetHeight来在.scroll-content变量中包含填充。

您可以在this文章中找到有关cntHeight媒体资源的更多信息。