使用HTML select标签修改JS变量时提示changeX未定义如何解决?
问题根源
你猜测的没错,就是函数嵌套导致的作用域问题:
changeX函数定义在getValueGraph函数的内部,仅在getValueGraph的函数作用域内可访问,而HTML行内的onchange事件绑定的是全局作用域下的函数,全局不存在changeX,就会抛出未定义的错误。- 你当前的逻辑也存在缺陷:图表渲染的逻辑全放在
changeX里,只有切换X轴的时候才会触发表格渲染,切换图表类型的时候不会更新图表,不符合你要同时切换类型和X轴的需求。
修复方案
建议把两个选择器的变更逻辑抽出来共享公共变量,调整后的代码如下:
第一步:修改HTML(推荐移除行内事件绑定,用JS绑定更易维护)
<div class='col-12 XDropDown'> <select id="SelectXValue"> <option value="" selected disabled hidden>Kies de X as</option> </select> </div> <div class='col-12 TraceType'> <select id="Trace_Type"> <option value="histogram">histogram</option> <option value="scatter">scatter</option> <option value="bar">bar</option> </select> </div>
第二步:调整JavaScript逻辑
var select = document.getElementById('SelectXValue'); var traceTypeSelect = document.getElementById('Trace_Type'); // 全局存储当前选中的图表类型 let currentTraceType = 'histogram'; for (let key of Object.keys(allColumns)) { var opt = document.createElement('option'); opt.value = key; opt.innerHTML = key; select.appendChild(opt); } // 抽离公共的图表渲染函数 function renderGraph(staticX) { var traces = []; for (let key of Object.keys(allColumns)) { var trace = { type: currentTraceType, histfunc: 'sum', name: key, x: staticX, y: allColumns[key], visible: 'legendonly', }; traces.push(trace); } var layout = { title: '', autosize: false, width: 1500, height: 750, xaxis: { showticklabels: true, tickangle: 'auto', tickfont: { family: 'Old Standard TT, serif', size: 14, color: 'black' }, showexponent: 'all', tickmode: 'array', ticktext: 'date', }, yaxis: { showticklabels: true, tickangle: 45, tickfont: { family: 'Old Standard TT, serif', size: 14, color: 'black' }, showexponent: 'all' }, }; Plotly.newPlot('graph', traces, layout); } // 图表类型切换事件 traceTypeSelect.addEventListener('change', function() { currentTraceType = this.value; // 已选中X轴的情况下直接更新图表 if (select.value) { renderGraph(allColumns[select.value]); } }); // X轴选择切换事件 select.addEventListener('change', function() { if (!this.value) return; renderGraph(allColumns[this.value]); });
调整后逻辑说明
- 两个选择器的事件都通过JS绑定,不需要依赖全局函数,从根源避免作用域问题
- 抽离公共的渲染函数,不管是切换图表类型还是切换X轴,都可以调用同一个方法更新图表
- 用全局变量
currentTraceType存储当前选中的图表类型,两个选择器的变更都可以读取到最新值
如果不想修改HTML的行内事件绑定,只需要把changeX函数从getValueGraph内部移到全局作用域,同时把tracetype改成全局共享变量即可,但更推荐用上述事件监听的方式,避免全局函数污染。
内容的提问来源于stack exchange,提问作者thijs
相关产品推荐
相关产品推荐

