Spaces:
Running
Running
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Virtual List Implementation</title> | |
| </head> | |
| <body> | |
| <script> | |
| class VirtualList { | |
| constructor(options) { | |
| this.container = options.w; | |
| this.itemHeight = options.itemHeight; | |
| this.totalRows = options.totalRows; | |
| this.generatorFn = options.generatorFn; | |
| this.visibleItems = Math.ceil(this.container.clientHeight / this.itemHeight); | |
| this.startIndex = 0; | |
| this.content = document.createElement('div'); | |
| this.content.style.position = 'relative'; | |
| this.content.style.height = `${this.totalRows() * this.itemHeight}px`; | |
| this.container.appendChild(this.content); | |
| this.renderChunk(this.startIndex); | |
| this.container.addEventListener('scroll', () => { | |
| const scrollTop = this.container.scrollTop; | |
| const newStartIndex = Math.floor(scrollTop / this.itemHeight); | |
| if (newStartIndex !== this.startIndex) { | |
| this.startIndex = newStartIndex; | |
| this.renderChunk(this.startIndex); | |
| } | |
| }); | |
| } | |
| renderChunk(startIndex) { | |
| // Clear existing content | |
| while (this.content.firstChild) { | |
| this.content.removeChild(this.content.firstChild); | |
| } | |
| // Add new content | |
| const endIndex = Math.min(startIndex + this.visibleItems + 2, this.totalRows()); | |
| for (let i = startIndex; i < endIndex; i++) { | |
| const item = document.createElement('div'); | |
| item.style.position = 'absolute'; | |
| item.style.top = `${i * this.itemHeight}px`; | |
| item.style.width = '100%'; | |
| const content = this.generatorFn(i); | |
| item.appendChild(content); | |
| this.content.appendChild(item); | |
| } | |
| } | |
| } | |
| // Make available globally | |
| window.VirtualList = VirtualList; | |
| </script> | |
| </body> | |
| </html> |