* Render visible items
()
| 79 | * Render visible items |
| 80 | */ |
| 81 | render() { |
| 82 | if (!this.items.length) { |
| 83 | this.topSpacer.style.height = "0px"; |
| 84 | this.bottomSpacer.style.height = "0px"; |
| 85 | return; |
| 86 | } |
| 87 | |
| 88 | const scrollTop = this.container.scrollTop; |
| 89 | const viewportHeight = this.container.clientHeight; |
| 90 | |
| 91 | // Calculate visible range |
| 92 | const startIndex = Math.max( |
| 93 | 0, |
| 94 | Math.floor(scrollTop / this.itemHeight) - this.buffer, |
| 95 | ); |
| 96 | const endIndex = Math.min( |
| 97 | this.items.length, |
| 98 | Math.ceil((scrollTop + viewportHeight) / this.itemHeight) + this.buffer, |
| 99 | ); |
| 100 | |
| 101 | // Skip if range hasn't changed |
| 102 | if ( |
| 103 | startIndex === this.renderedRange.start && |
| 104 | endIndex === this.renderedRange.end |
| 105 | ) { |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | // Update spacers |
| 110 | this.topSpacer.style.height = `${startIndex * this.itemHeight}px`; |
| 111 | this.bottomSpacer.style.height = `${Math.max(0, (this.items.length - endIndex) * this.itemHeight)}px`; |
| 112 | |
| 113 | // Recycle existing elements |
| 114 | while (this.itemContainer.firstChild) { |
| 115 | const child = this.itemContainer.removeChild( |
| 116 | this.itemContainer.firstChild, |
| 117 | ); |
| 118 | this.pool.push(child); |
| 119 | } |
| 120 | |
| 121 | // Render visible items using DocumentFragment |
| 122 | const fragment = document.createDocumentFragment(); |
| 123 | |
| 124 | for (let i = startIndex; i < endIndex; i++) { |
| 125 | const item = this.items[i]; |
| 126 | const recycledEl = this.pool.pop(); |
| 127 | const el = this.renderItem(item, recycledEl); |
| 128 | el.style.height = `${this.itemHeight}px`; |
| 129 | fragment.appendChild(el); |
| 130 | } |
| 131 | |
| 132 | this.itemContainer.appendChild(fragment); |
| 133 | this.renderedRange = { start: startIndex, end: endIndex }; |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * Scroll to a specific item index |
no outgoing calls
no test coverage detected