AJAX调用与图表加载时Bootstrap下拉框消失问题求助
问题
执行AJAX调用或首次加载图表时,HTML中用Bootstrap定义的下拉框所在区域会消失。
相关代码
HTML代码
<div class="col-md-6"> <h2>Certificates Report using Google Chart</h2> <div id="certificate-container"> <div class="form-group"> <div class="col-md-4"> <label for="days_cert">Interval:</label> <select name="days" id="days_cert" class="form-control table-filter"> <option value="1">1 day ago</option> <option value="7">7 days ago</option> <option value="30">1 month ago</option> <option value="90">3 month ago</option> <option value="365" selected>1 year ago</option> <option value="730">2 year ago</option> </select> </div> </div> <div id="chart-container"> <div id="chart_div"></div> <div id="piechart" style="width: 500px; height: 300px;"></div> </div> </div> </div>
JavaScript代码
var real_data; var real_data_payment; var real_data_enrollment; var requestInput; var dataCert; var requestInputPay; var dataPay; var requestInputEnroll; var dataEnroll; days_cert.addEventListener('change', function() { requestInput = new RequestInput($("#days_cert").val()); dataCert = JSON.stringify(requestInput); updateChartDataCertificate(); loadCharts(); }); requestInput = new RequestInput($("#days_cert").val()); dataCert = JSON.stringify(requestInput); function updateChartDataCertificate() { $.ajax({ type: 'POST', url: '/api/charts/certificates/count', data: dataCert, contentType: "application/json", dataType: "json", success: function(response) { console.log(dataCert); real_data = response; console.log(real_data); }, error: function(xhr, status, error) { var requestInput = new RequestInput($("#days_cert").val()); console.log(JSON.stringify(requestInput)); } }); } $(document).ready(function() { updateChartDataCertificate(); loadCharts(); }); function loadCharts() { google.charts.load('current', { packages : [ 'corechart', 'bar' ] }); google.charts.setOnLoadCallback(drawColumnChart); google.charts.setOnLoadCallback(drawPieChart); } function RequestInput(days) { this.days = days; } function drawColumnChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Type'); data.addColumn('number', 'Count'); console.log(real_data); Object.keys(real_data).forEach(function(key) { data.addRow([ key, real_data[key] ]); }); var options = { title : 'Certificate Stats', chartArea: { bottom: 40 }, hAxis : { title : 'Type', textStyle: { fontSize: 8, fontStyle: "Arial", marginTop: '25' } }, vAxis : { title : 'Count' } }; var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); chart.draw(data, options); } function drawPieChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Type'); data.addColumn('number', 'Count'); Object.keys(real_data).forEach(function(key) { data.addRow([ key, real_data[key] ]); }); var options = { title : 'Certificate Stats', is3D: true, pieSliceTextStyle: { fontSize: 8 } }; var chart = new google.visualization.PieChart(document.getElementById('piechart')); chart.draw(data, options); }
现象说明
- 操作前:下拉框正常显示,图表区域未完全渲染
- 操作后:下拉框所在区域消失,仅图表区域保留
解决方案
问题根源
- 重复加载Google Charts:每次下拉框变化或页面加载时都调用
google.charts.load(),该方法会重置页面部分DOM结构,导致下拉框被意外清除。 - 异步请求时序错误:AJAX请求是异步的,调用
updateChartDataCertificate()后立刻执行loadCharts(),此时real_data还未更新,不仅图表会出错,还会触发重复加载逻辑。 - Bootstrap布局嵌套错误:
form-group与栅格列col-md-4的嵌套不符合Bootstrap规范,容易被图表渲染的样式干扰。
修改步骤
1. 调整JavaScript代码,避免重复加载Google Charts
将Google Charts的加载逻辑移到全局,仅执行一次;并将图表绘制逻辑放到AJAX请求的成功回调中,确保数据更新后再渲染图表。
修改后的JavaScript代码:
var real_data; var real_data_payment; var real_data_enrollment; var requestInput; var dataCert; var requestInputPay; var dataPay; var requestInputEnroll; var dataEnroll; // 仅加载一次Google Charts google.charts.load('current', { packages: ['corechart', 'bar'] }); // 加载完成后初始化数据和图表 google.charts.setOnLoadCallback(function() { requestInput = new RequestInput($("#days_cert").val()); dataCert = JSON.stringify(requestInput); updateChartDataCertificate(); }); // 下拉框变化时仅触发数据请求 days_cert.addEventListener('change', function() { requestInput = new RequestInput($("#days_cert").val()); dataCert = JSON.stringify(requestInput); updateChartDataCertificate(); }); function updateChartDataCertificate() { $.ajax({ type: 'POST', url: '/api/charts/certificates/count', data: dataCert, contentType: "application/json", dataType: "json", success: function(response) { real_data = response; // 数据更新后直接绘制图表 drawColumnChart(); drawPieChart(); }, error: function(xhr, status, error) { var requestInput = new RequestInput($("#days_cert").val()); console.log(JSON.stringify(requestInput)); } }); } function RequestInput(days) { this.days = days; } function drawColumnChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Type'); data.addColumn('number', 'Count'); Object.keys(real_data).forEach(function(key) { data.addRow([key, real_data[key]]); }); var options = { title: 'Certificate Stats', chartArea: { bottom: 40 }, hAxis: { title: 'Type', textStyle: { fontSize: 8, fontStyle: "Arial" } }, vAxis: { title: 'Count' } }; var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); chart.draw(data, options); } function drawPieChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Type'); data.addColumn('number', 'Count'); Object.keys(real_data).forEach(function(key) { data.addRow([key, real_data[key]]); }); var options = { title: 'Certificate Stats', is3D: true, pieSliceTextStyle: { fontSize: 8 } }; var chart = new google.visualization.PieChart(document.getElementById('piechart')); chart.draw(data, options); }
2. 修正Bootstrap布局结构
调整表单区域的嵌套,用row包裹表单组,确保栅格布局符合Bootstrap规范,避免样式冲突。
修改后的HTML代码:
<div class="col-md-6"> <h2>Certificates Report using Google Chart</h2> <div id="certificate-container"> <!-- 用row包裹表单,确保栅格布局正确 --> <div class="row"> <div class="form-group col-md-4"> <label for="days_cert">Interval:</label> <select name="days" id="days_cert" class="form-control table-filter"> <option value="1">1 day ago</option> <option value="7">7 days ago</option> <option value="30">1 month ago</option> <option value="90">3 month ago</option> <option value="365" selected>1 year ago</option> <option value="730">2 year ago</option> </select> </div> </div> <div id="chart-container"> <div id="chart_div"></div> <div id="piechart" style="width: 500px; height: 300px;"></div> </div> </div> </div>
修改说明
- 移除了重复的
google.charts.load()调用,避免DOM重置导致下拉框消失。 - 将图表绘制逻辑绑定到AJAX请求的成功回调,确保数据更新后再渲染图表,解决时序问题。
- 修正Bootstrap栅格嵌套,避免图表渲染时破坏表单区域的布局。
内容的提问来源于stack exchange,提问作者ahad alam
相关产品推荐
相关产品推荐

