Reputation: 526
I am currently working on a custom table that I have made with knockoutJS and jQuery. Because this table is possibly dealing with 1,000 - 100,000 rows, I have implemented my own virtual scrolling technique in KnockoutJS to ensure that only 35 or so elements are visible at a time (depending on viewport height). When scrolling with the scroll-wheel, the table's tr elements are dynamically updated in-place to give the illusion of scrolling. This much works.
However, I need to think of a way to implement fake scrollbars. I am needing a fake scrollbar that does not actually scroll the page, but rather calls a function when dragged so that I can re-direct that info to my knockoutJS virtual scroller for updating the tr elements.
I have looked a bit into jScrollPane, but am not sure if it will support what I want. Does anyone else have experience with this?
Thanks.
Upvotes: 1
Views: 718
Reputation: 43899
Here's a rough demo of doing it with actual scrollbars and scrolling. You can see it better if you make the snippet full-screen.
The idea is that you have a window of visible items, somewhat like you have already, but it is displayed in fixed
position over a tall, scrolling window. When the window is scrolled, you find its new position and use that to recompute which of your items should be visible.
As it is here, I had to put in a fudge factor to get to the last items in the list. I did say it's a "rough" demo.
const vm = {
items: ko.observableArray([]),
percent: ko.observable(0),
visibleItems: ko.pureComputed(() => {
const start = Math.floor(vm.percent() * vm.items().length);
return vm.items.slice(start, start + 22);
})
};
for (let i = 0; i < 5000; ++i) {
vm.items.push(i);
}
ko.bindingHandlers.scroll = {
init: (el, va) => {
let top = el.parentNode.scrollTop;
const percent = va();
setInterval(() => {
const newTop = el.parentNode.scrollTop;
if (newTop !== top) {
percent(newTop / (0.859 * el.parentNode.scrollHeight));
top = newTop;
}
}, 50);
}
};
ko.applyBindings(vm);
.scroll-me {
background-color: rgba(255, 30, 30, 0.3);
height: 3000px;
}
.all-you-see {
background-color: white;
width: 100%;
position: fixed;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="scroll-me" data-bind="scroll: percent">
<div class="all-you-see">
<div data-bind="foreach:visibleItems">
<div data-bind="text:$data"></div>
</div>
</div>
</div>
Upvotes: 1