HyperList
This is a simple component that can be dropped into any JavaScript application
and provide a virtual scrolling area that is highly performant and lightweight.
With zero dependencies and well under 300 lines of code sans comments, it is
easy to understand and use.
Demo
Installation
npm install hyperlist
Of course it can also just be added to any JavaScript project since it consists
of a single JavaScript file.
Usage
Below are full code examples containing typical usage. Documentation
supplements the code comments so hopefully everything makes sense!
Invocation
How to invoke an instance of HyperList
const list = HyperList.create(document.body, requiredOptions);
const list = new HyperList(document.body, requiredOptions);
Required Options
These configuration options are not optional. So set them to avoid runtime
errors. You can mutate them by setting a new object in the refresh method.
list.refresh(element, newConfig);
itemHeight
A single value that is the height for every single element in
the list.total
The number of items in the list.generate
A function that is called with the index to render. You return an
element to render in that position.
Basic example
A simple example with just the required options.
const container = document.createElement('div');
const list = HyperList.create(container, {
itemHeight: 30,
total: 10000,
generate(index) {
const el = document.createElement('div');
el.innerHTML = `ITEM ${index + 1}`;
return el;
},
});
document.body.appendChild(container);
Optional Options
These configuration options are totally optional. So set them when you need to
go beyond the defaults and required options.
reverse
This will render items from the bottom of the container instead of
the top. This works much better for chat and notifications experiences. This
option will automatically scroll the container to the bottom every time the
refresh method is called and during instantiation.horizontal
Change the rendering orientation to horizontalwidth
The container width as a number or string (defaults to 100%
)height
The container height as a number or string (defaults to 100%
)scrollerTagName
Is a TR by default which works fine in most cases. If you
need a different element tag name, specify it here.rowClassName
Any custom classes to add to the row.overrideScrollPosition
Pull the scrollTop value from somewhere else, this
allows for binding range elements to the scroll position.applyPatch
Is called with the container element and the DocumentFragment
which contains all the items being added. You can implement Virtual DOM
patching with this hook.afterRender
- Triggered after applyPatch
has returned.scroller
- Specify an element to be in the place of the scroller.useFragment
- Determines if a fragment is used internally or not, defaults
to true.
Variable height items
When you are rendering a list of elements that have variable heights you may
specific an object as the generate
callback's return value that contains
the signature: { element: domNode, height: 100 }
.
For example:
generate(index) {
const el = document.createElement('div');
el.innerHTML = `ITEM ${index + 1}`;
return { element: el, height: Math.random() * 1000 };
}
You can also find a working implementation in the examples directory.
Advanced example
An example with all the options, mounted to the entire page that refreshes when
the browser resizes.
const container = document.createElement('div');
const config = {
width: '100%',
height: window.innerHeight,
itemHeight: 30,
total: 10000,
reverse: true,
scrollerTagName: 'tr',
scroller: document.createElement('tr'),
rowClassName: 'vrow',
useFragment: false,
overrideScrollPosition() {
return document.body.scrollTop;
},
generate(index) {
const el = document.createElement('div');
el.innerHTML = `ITEM ${index + 1}`;
return el;
},
afterRender() {
console.log('Rendered some items');
},
applyPatch(element, fragment) {
element.innerHTML = '';
element.appendChild(fragment);
},
};
const list = HyperList.create(container, config);
window.onresize = () => {
config.height = window.innerHeight;
list.refresh(container, config);
};
document.body.appendChild(container);
Contributing
PRs are welcome, please ensure the tests pass and the code looks like the
surrounding style:
npm test
Credits
This project is a fork of the existing (unmaintained) project:
https://github.com/sergi/virtual-list
This README section, the LICENSE, and package.json will remain to ensure
proper credit is always extended.