You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTMX发起GET请求加载含Chart.js画布的HTML片段时图表无法渲染的问题咨询

完全可以实现!问题出在脚本加载顺序和执行时机上

你的思路是对的——用HTMX异步加载包含Chart.js画布的HTML片段完全可行,只是当前代码里的脚本加载逻辑有问题,导致图表初始化代码执行时Chart对象还没准备好。

问题分析

你把Chart.js的核心库放在了异步加载的HTML片段里,而<script>标签默认是异步加载的。这就导致片段里的图表初始化代码(new Chart(...))会在Chart.js核心库下载并解析完成之前执行,自然会抛出Chart is not defined的错误,图表也就生成不了。

另外,主页面里已经加载了Chart.js的依赖插件(adapter、hammer、zoom),但缺少核心的Chart.js库,这也会影响插件的正常工作。

修复步骤

1. 将Chart.js核心库移到主页面加载

把片段里的Chart.js引入脚本移到主页面的<body>末尾,确保在HTMX发起请求前,Chart对象就已经存在:

修改后的主页面代码:

<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/htmx.org@1.6.1" integrity="sha384-tvG/2mnCFmGQzYC1Oh3qxQ7CkQ9kMzYjWZSNtrRZygHPDDqottzEJsqS4oUVodhW" crossorigin="anonymous"></script>
<div id="mainAjax" class="slide-in-left-fade-in fade-me-out fade-in">
<button class="" hx-get="/data-viz/simple-chart" hx-target="#mainAjax" hx-swap="outerHTML swap:0.2s" hx-select="#mainAjax" hx-trigger="myEvent from:body">
Get canvas
</button>
</div>
<script>
document.body.addEventListener("myEvent", function(evt) {
alert("trigger is working")
})
</script>
<!-- 先加载Chart.js核心库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js" integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- 再加载依赖插件 -->
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.0/chartjs-plugin-zoom.min.js" integrity="sha512-TT0wAMqqtjXVzpc48sI0G84rBP+oTkBZPgeRYIOVRGUdwJsyS3WPipsNh///ay2LJ+onCM23tipnz6EvEy2/UA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
</html>

2. 移除片段里的Chart.js引入

因为主页面已经加载了核心库,片段里不需要重复引入,避免冗余和潜在的加载冲突:

修改后的HTML片段代码:

<div id="mainAjax" class="">
<canvas class="my-4 w-100 chartjs-render-monitor" id="myChart" width="1110" height="468" style="display: block; height: 521px; width: 1234px;"></canvas>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
var config = {
 type: 'line',
 data: {
 labels : ['2005-03-31', '2005-06-30', '2005-09-30', '2005-12-31', '2006-03-31', '2006-06-30', '2006-09-30', '2006-12-31', '2007-03-31', '2007-06-30', '2007-09-30', '2007-12-31', '2008-03-31', '2008-06-30', '2008-09-30', '2008-12-31', '2009-03-31', '2009-06-30', '2009-09-30', '2009-12-31', '2010-03-31', '2010-06-30', '2010-09-30', '2010-12-31', '2011-03-31', '2011-06-30', '2011-09-30', '2011-12-31', '2012-03-31', '2012-06-30', '2012-09-30', '2012-12-31', '2013-03-31', '2013-06-30', '2013-09-30', '2013-12-31', '2014-03-31', '2014-06-30', '2014-09-30', '2014-12-31', '2015-03-31', '2015-06-30', '2015-09-30', '2015-12-31', '2016-03-31', '2016-06-30', '2016-09-30', '2016-12-31', '2017-03-31', '2017-06-30', '2017-09-30', '2017-12-31', '2018-03-31', '2018-06-30', '2018-09-30', '2018-12-31', '2019-03-31', '2019-06-30', '2019-09-30', '2019-12-31', '2020-03-31', '2020-06-30', '2020-09-30', '2020-12-31', '2021-03-31', '2021-06-30', '2021-09-30'],
 datasets: [{ label: 'AAPL Revenue', lineTension: 0, data: [3243.0, 3520.0, 3678.0, 5749.0, 4359.0, 4370.0, 4837.0, 7115.0, 5264.0, 5410.0, 6789.0, 9608.0, 7512.0, 7464.0, 12907.0, 11880.0, 9084.0, 9734.0, 12207.0, 15683.0, 13499.0, 15700.0, 20343.0, 26741.0, 24667.0, 28571.0, 28270.0, 46333.0, 39186.0, 35023.0, 35966.0, 54512.0, 43603.0, 35323.0, 37472.0, 57594.0, 45646.0, 37432.0, 42123.0, 74599.0, 58010.0, 49605.0, 51501.0, 75872.0, 50557.0, 42358.0, 46852.0, 78351.0, 52896.0, 45408.0, 52579.0, 88293.0, 61137.0, 53265.0, 62900.0, 84310.0, 58015.0, 53809.0, 64040.0, 91819.0, 58313.0, 59685.0, 64698.0, 111439.0, 89584.0, 81434.0, 83360.0], backgroundColor: '#A3BE8C4D', fill: false, showLine : true, borderColor: '#A3BE8C' , borderWidth: 1 }],
 },
}
var myChart = new Chart(ctx, config);
console.log(myChart.data.datasets)
document.body.addEventListener("cart-updated", function (evt) {
alert("cart updated")
})
</script>
</div>

3. 额外注意事项

  • HTMX会自动执行加载的HTML片段中的<script>标签,所以不需要额外手动触发代码执行。
  • 如果后续需要动态更新图表数据,可以通过HTMX的事件(比如htmx:afterSwap)来监听内容加载完成,再执行更新逻辑。
  • 确保所有Chart.js的依赖插件(adapter、zoom等)都在核心库之后加载,这是Chart.js插件的要求。

这样修改后,当你点击按钮触发HTMX请求时,加载的片段里的初始化代码就能正常访问到已经加载好的Chart对象,图表也就会正确渲染出来了。

内容的提问来源于stack exchange,提问作者Paul Marmagne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:32:38