使用js写一个虚拟滚动的小组件

创建一个简单的虚拟滚动组件需要考虑几个关键部分:

  1. 可视区域:用户实际看到的部分。
  2. 滚动容器:包含所有内容的容器,其高度可能远远超过可视区域。
  3. 占位元素:在滚动容器的上下方放置的空白元素,用于模拟滚动效果。
  4. 滚动逻辑:当用户滚动时,更新可视区域显示的内容。

以下是一个简化的虚拟滚动组件的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Virtual Scroll Demo</title>
    <style>
        #viewport {
            height: 300px;
            overflow-y: scroll;
            position: relative;
        }
        .phantom {
            height: 1px; /* Adjust based on item height and count */
        }
        .item {
            height: 50px;
            line-height: 50px;
            text-align: center;
            border-bottom: 1px solid #ccc;
            position: absolute;
            width: 100%;
        }
    </style>
</head>
<body>
    <div id="viewport">
        <div class="phantom" id="phantom-top"></div>
        <!-- Items will be dynamically added here -->
        <div class="phantom" id="phantom-bottom"></div>
    </div>
    <script>
        const itemHeight = 50; // Height of each item
        const itemCount = 1000; // Total number of items
        const viewport = document.getElementById('viewport');
        const phantomTop = document.getElementById('phantom-top');
        const phantomBottom = document.getElementById('phantom-bottom');
        let startIndex = 0; // Index of the first visible item
        let endIndex = Math.min(itemCount, Math.ceil(viewport.clientHeight / itemHeight) + startIndex); // Index of the last visible item

        function updateItems() {
            // Clear previous items
            const items = document.querySelectorAll('.item');
            items.forEach(item => item.remove());
            
            // Add new items based on startIndex and endIndex
            for (let i = startIndex; i < endIndex; i++) {
                const item = document.createElement('div');
                item.className = 'item';
                item.style.top = `${i * itemHeight}px`;
                item.textContent = `Item ${i + 1}`;
                viewport.appendChild(item);
            }
        }

        function onScroll() {
            const scrollTop = viewport.scrollTop;
            startIndex = Math.floor(scrollTop / itemHeight);
            endIndex = Math.min(itemCount, Math.ceil((scrollTop + viewport.clientHeight) / itemHeight));
            updateItems();
        }

        // Set initial phantom heights to simulate full content height
        phantomTop.style.height = `${startIndex * itemHeight}px`;
        phantomBottom.style.height = `${(itemCount - endIndex) * itemHeight}px`;
        viewport.scrollTop = 0; // Reset scroll position to top
        updateItems(); // Initial item rendering
        viewport.addEventListener('scroll', onScroll); // Listen for scroll events to update items dynamically
    </script>
</body>
</html>

这个示例创建了一个简单的虚拟滚动效果,其中只渲染了可视区域内的项目。当用户滚动时,会动态更新显示的项目。注意,这个示例是为了简化而设计的,并没有考虑性能优化、边缘情况处理或复杂的布局需求。在实际应用中,可能需要更复杂的逻辑和优化来确保流畅的用户体验和高效的内存使用。

posted @ 2024-12-26 09:52  王铁柱6  阅读(32)  评论(0)    收藏  举报