HTMX加载Chart.js图表不显示,报Chart未定义错误求助
问题:Flask+HTMX加载Chart.js图表无法渲染,控制台提示Chart未定义
我用Flask和Python搭建仪表盘,通过HTMX调用图表组件,但图表显示不出来。查看页面元素能看到对应的script、canvas和代码,就是看不到可视化的图表。
前置调用代码
<div> <div class="toolbox"> <h1>Budget</h1> <div> <div hx-get="/auth/budget/expense_form" hx-swap="innerHTML" hx-trigger="load once" id="expense_form_field"> </div> <div hx-get="/auth/budget/dashboard" hx-swap="outerHTML" id="dashboard" hx-target="#dashboard" hx-trigger="load once"> </div> </div> </div> </div>
HTMX返回的HTML内容
<div> <canvas id="myChart"></canvas> </div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> const ctx = document.getElementById('myChart'); const chart = new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); </script>
控制台报错
Uncaught ReferenceError: Chart is not defined at <anonymous>:4:19 at At (htmx.org@1.9.10:1:22924) at Nt (htmx.org@1.9.10:1:23051) at htmx.org@1.9.10:1:10309 at htmx.org@1.9.10:1:44741 at oe (htmx.org@1.9.10:1:4604) at s (htmx.org@1.9.10:1:44716)
观察到的异常
浏览器元素中,生成的脚本带有htmx-settling类标签,怀疑这会干扰脚本运行:
<script class="htmx-settling"> const ctx = document.getElementById('myChart'); const chart = new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); </script>
解决方案
1. 提前加载Chart.js到主页面
把Chart.js的CDN引用放到仪表盘的主页面(而非HTMX返回的片段里),确保HTMX加载脚本时,Chart对象已存在。
主页面头部添加:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/chart.js"></script>
2. 让HTMX等待脚本加载完成再执行
如果必须在HTMX片段里加载Chart.js,修改返回内容,通过onload事件确保库加载完成后再初始化图表:
<div> <canvas id="myChart"></canvas> </div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/chart.js" onload="initChart()"></script> <script> function initChart() { const ctx = document.getElementById('myChart'); new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); } </script>
3. 利用HTMX事件触发器初始化图表
在主页面添加全局事件监听,借助htmx:afterSettle事件确保DOM更新完成后再执行图表初始化:
document.body.addEventListener('htmx:afterSettle', function(event) { if (event.target.id === 'dashboard') { const ctx = document.getElementById('myChart'); if (ctx && typeof Chart !== 'undefined') { new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); } } });
同时HTMX返回的内容仅保留canvas标签即可。
内容的提问来源于stack exchange,提问作者stuart-kieser
相关产品推荐
相关产品推荐

