实现滚动到对应区域时渲染多个Chart.js图表
实现Chart.js图表滚动触发加载
核心思路
- 预先存储所有图表的配置与数据,不立即执行初始化
- 监听页面滚动事件,检测图表容器是否进入接近视口的区域(可自定义触发提前量)
- 一旦容器可见且未初始化,立即创建Chart实例,同时标记状态避免重复执行
修改后的代码实现
HTML部分
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script> <div class="blankDiv" style="height: 700px;width: 100%;"> Scroll Down to See the chart </div> <!-- 给图表容器添加统一类名,方便批量选择 --> <div class="chart-container" style="max-width: 70em;"> <canvas id="myChart"></canvas> </div> <div class="blankDiv" style="height: 700px;width: 100%;"> Scroll Down to See the chart </div> <div class="chart-container" style="max-width: 70em;"> <canvas id="myChart2"></canvas> </div>
JavaScript部分
// 预存所有图表的配置信息,暂不初始化 const chartConfigs = [ { canvasId: 'myChart', config: { type: 'bar', data: { labels: ['one', 'two', 'three', 'four'], datasets: [{ label: '% of Respondents', data: [55, 51, 46, 36], backgroundColor: [ 'rgba(79, 38, 131, 0.8)', 'rgba(79, 38, 131, 0.6)', 'rgba(79, 38, 131, 0.4)', 'rgba(79, 38, 131, 0.2)' ] }] }, options: { scales: { y: { beginAtZero: true } }, indexAxis: 'y' } }, initialized: false // 标记是否已完成初始化 }, { canvasId: 'myChart2', config: { type: 'bar', data: { labels: ['one', 'two', 'three', 'four'], datasets: [{ label: '% of Respondents', data: [55, 51, 46, 36], backgroundColor: [ 'rgba(79, 38, 131, 0.8)', 'rgba(79, 38, 131, 0.6)', 'rgba(79, 38, 131, 0.4)', 'rgba(79, 38, 131, 0.2)' ] }] }, options: { scales: { y: { beginAtZero: true } }, indexAxis: 'y' } }, initialized: false } ]; // 检测元素是否进入触发加载的区域 function isElementInViewport(el) { const rect = el.getBoundingClientRect(); // 元素顶部距离视口底部小于200px时,触发加载(可调整提前量) return rect.top <= window.innerHeight + 200; } // 初始化当前可见/即将可见的图表 function initVisibleCharts() { chartConfigs.forEach(chartItem => { if (!chartItem.initialized) { const container = document.querySelector(`#${chartItem.canvasId}`).parentElement; if (isElementInViewport(container)) { new Chart(document.getElementById(chartItem.canvasId), chartItem.config); chartItem.initialized = true; } } }); } // 页面加载时先检查一次,确保首屏图表能正常加载 window.addEventListener('load', initVisibleCharts); // 防抖处理:减少滚动事件触发频率,优化性能 let debounceTimer; window.addEventListener('scroll', () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(initVisibleCharts, 100); });
关键细节说明
- 容器检测:以图表的父容器为检测目标,确保滚动到容器附近就触发加载
- 防抖优化:通过定时器延迟执行检查逻辑,避免滚动时频繁触发函数
- 初始化标记:每个图表配置中添加
initialized属性,防止重复创建Chart实例 - 触发阈值:
window.innerHeight + 200可根据需求调整,数值越大图表加载时机越早
内容的提问来源于stack exchange,提问作者kimkim
相关产品推荐
相关产品推荐

