JavaScript更新HTML触发defer相关TypeError与ReferenceError问题求助
问题原因及解决方案
报错根源解释
- 未给script加defer时的报错:head中的script执行时DOM还未完成解析,
document.getElementById("car-details")返回null,操作null的innerHTML属性触发类型错误。 - 两个script都加defer时的报错:
defer属性仅对外部引入的script标签生效,内联script添加defer不会延迟执行,因此内联脚本运行时,外部的breakeven-calc.js还未加载完成,找不到updateDetailsHTML函数触发引用错误。
最优解决方案
调整script标签的位置和加载顺序,去掉所有defer属性,把script放到body末尾,保证DOM元素渲染完成、依赖的函数先加载完成再执行业务逻辑,修改后代码如下:
<head> <!-- 头部不放置业务相关script --> </head> <body> <p id="car-details"> Pre-ownership CO2e emissions (reference values apply): <br> EV: MTCO2e/Year <br> ICEV: MTCO2e/Year </p> <!-- 先引入外部JS,保证函数先定义 --> <script src="../static/js/breakeven-calc.js"></script> <!-- 再执行业务逻辑 --> <script type="text/javascript"> let G22_Car = parseFloat("{{data.get('G22_Car')}}") let G23_Car = parseFloat("{{data.get('G23_Car')}}") let Q23_Car = parseFloat("{{data.get('Q23_Car')}}") let Q24_Car = parseFloat("{{data.get('Q24_Car')}}") let G22_Truck = parseFloat("{{data.get('G22_Car')}}") let G23_Truck = parseFloat("{{data.get('G23_Car')}}") let Q23_Truck = parseFloat("{{data.get('Q23_Truck')}}") let Q24_Truck = parseFloat("{{data.get('Q24_Truck')}}") let pre_icev_car = G22_Car + G23_Car let pre_ev_car = Q23_Car + Q24_Car let pre_icev_truck = G22_Truck + G23_Truck let pre_ev_truck = Q23_Truck + Q24_Truck console.log(pre_ev_car) console.log(pre_icev_car) console.log(pre_ev_truck) console.log(pre_icev_truck) updateDetailsHTML(pre_icev_car, pre_ev_car, pre_icev_truck, pre_ev_truck) </script> </body>
替代方案(script保留在head中)
如果必须把script放在head里,可以保留外部脚本的defer属性,去掉内联脚本的defer,把逻辑包在DOMContentLoaded事件监听中即可:
<head> <script defer src="../static/js/breakeven-calc.js"></script> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function() { let G22_Car = parseFloat("{{data.get('G22_Car')}}") let G23_Car = parseFloat("{{data.get('G23_Car')}}") let Q23_Car = parseFloat("{{data.get('Q23_Car')}}") let Q24_Car = parseFloat("{{data.get('Q24_Car')}}") let G22_Truck = parseFloat("{{data.get('G22_Car')}}") let G23_Truck = parseFloat("{{data.get('G23_Car')}}") let Q23_Truck = parseFloat("{{data.get('Q23_Truck')}}") let Q24_Truck = parseFloat("{{data.get('Q24_Truck')}}") let pre_icev_car = G22_Car + G23_Car let pre_ev_car = Q23_Car + Q24_Car let pre_icev_truck = G22_Truck + G23_Truck let pre_ev_truck = Q23_Truck + Q24_Truck console.log(pre_ev_car) console.log(pre_icev_car) console.log(pre_ev_truck) console.log(pre_icev_truck) updateDetailsHTML(pre_icev_car, pre_ev_car, pre_icev_truck, pre_ev_truck) }) </script> </head>
注意:原有引入路径中的多余双斜杠
../static//js/建议修改为单斜杠,避免出现路径异常。
内容的提问来源于stack exchange,提问作者pdsatter
相关产品推荐
相关产品推荐

