在使用 AJAX 動態載入 Highcharts 圖表時,發現第一次點擊按鈕可以正常顯示圖表,但第二次點擊即報錯:Uncaught exception: Highcharts error #16。官方文檔說明此錯誤代表「頁面上已存在該容器,無法重複建立」。
Highcharts 在初始化時會將圖表實例綁定到指定的 DOM 容器(如 div#container)。若同一容器重複調用 $('#container').highcharts({...}) 而未銷毀先前實例,Highcharts 會拋出錯誤 #16。AJAX 回調中直接將 HTML 片段(包含 <script> 標籤)插入頁面,導致每次請求都嘗試在同一個 #container 上建立新圖表,從而觸發衝突。
在 AJAX 成功回調中,先檢查容器是否已有 Highcharts 實例,若有則銷毀:
success: function (data) {
$("#show").html(data); // 先插入 HTML,確保 script 執行
// 若容器已有實例,先銷毀
if ($('#container').highcharts()) {
$('#container').highcharts().destroy();
}
// 此處無需再次初始化,因為插入的 HTML 中已包含初始化腳本
}
注意:bar.jsp 內的 <script>$(function(){ $('#container').highcharts(...) }) 會在 HTML 插入後自動執行,銷毀操作需在該腳本執行前完成,或改用手動初始化方式。
將圖表配置數據以 JSON 形式從後端返回,前端統一初始化:
// 後端返回 JSON:{ categories: [...], series: [{name: '...', data: [...]}] }
success: function (chartData) {
if ($('#container').highcharts()) {
$('#container').highcharts().destroy();
}
$('#container').highcharts({
chart: { type: 'column' },
title: { text: chartData.title },
xAxis: { categories: chartData.categories },
series: chartData.series
// 其他配置...
});
}
此做法將視圖邏輯集中前端,後端僅提供數據,更易維護。
function bar(param) {
$.ajax({
type: 'POST',
url: 'selbase.action',
data: { org_id: '<%=org_id%>', outtype: param, req_code: 'P110' },
cache: false,
success: function (data) {
$("#show").html(data);
// 若使用方法一,此處銷毀舊實例
},
error: function (xhr, status, err) {
console.error(status, err);
}
});
}
<div id="container" style="min-width:800px;height:400px"></div>
<script type="text/javascript">
$(function () {
// 若採用方法二,此處不應有初始化代碼,改由 AJAX 回調統一初始化
// 否則需確保前端在插入前銷毀舊實例
$('#container').highcharts({ ... });
});
</script>
核心在於「同一容器同一時間只能存在一個 Highcharts 實例」。通過 destroy() 銷毀舊實例,或改用 JSON 數據分離視圖與數據,即可解決多次 AJAX 載入圖表失效的問題。