我也在寻找这个问题的答案,所以我会分享我在哪里。
我有大量内容要垂直显示并让用户滚动浏览。我可以将它全部加载到 DOM 中并正常滚动,但初始创建阶段非常慢,滚动也非常慢。此外,当我流式传输更多数据时,我将动态添加到它。
所以我想要同样的东西,即能够动态填充和更新内容的非滚动区域。我想让它看起来好像用户正在滚动浏览该内容并拥有一个模型(其中包含大量数据),该模型远离 DOM,直到它被看到。
我想我将使用队列概念来管理可见的 DOM 元素。我会存储 queueHeadIndex 和 queueTailIndex 以记住 DOM 中显示了哪些非 DOM 元素。当用户向下滚动时,我会计算出队列头是否从屏幕上掉下来以及是否更新 queueHeadIndex 并删除它的 DOM 元素。其次,我会确定是否需要更新 queueTailIndex 并向 DOM 添加新元素。对于当前在 DOM 中的元素,我需要移动它们(不确定它们是否需要动画)。
更新:我发现这似乎有一些承诺http://jsfiddle.net/GdsEa/
我目前的想法是这个问题有两个部分。
首先,我想我想禁用滚动并进行某种虚拟滚动。我刚刚开始为此查看http://www.everyday3d.com/blog/index.php/2014/08/18/smooth-scrolling-with-virtualscroll/ 。这将捕获所有事件并使我能够以编程方式调整当前可见的内容等,但浏览器实际上不会滚动任何内容。这似乎提供了鼠标滚轮驱动的滚动。
其次,我认为我需要显示一个滚动条。我已经查看了http://codepen.io/chriscoyier/pen/gzBsA并且我正在寻找更多看起来更原生的东西。我只想让它直观地显示滚动的位置,并允许用户通过拖动滚动条来调整滚动位置。
Stackoverflow 坚持要我粘贴代码,所以这里是来自上面那个 codepen 链接的一些代码
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";
thumb.style.height = Math.round(trcHeight * height / cntHeight) + 'px';
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)
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);
}
我想我会有一个类通过虚拟滚动方法或 ui 来监听滚动事件,然后更新 ui 滚动器和我正在管理的内容的 ui。
无论如何,如果我发现任何更有用的东西,我会更新它。