Uncaught TypeError错误排查:无法读取null的addEventListener属性
错误原因排查与解决办法
直接触发Uncaught TypeError的原因
你的JS代码存在语法错误:$(document).ready的回调函数内部多了一个多余的闭合大括号},导致后续获取purchaseAmount元素、绑定事件的代码脱离了DOM就绪回调的范围,在页面DOM未完全加载完成时就执行了。此时#purchaseAmount元素还未被渲染,document.querySelector('#purchaseAmount')返回null,调用addEventListener自然会触发"Cannot read properties of null"错误。
其他影响功能的代码问题及修复
除了上述语法错误,还有多处问题导致运费计算功能无法正常运行:
- 提交按钮是
<a>标签而非<button>,JS中$("button").on('click', ...)无法匹配到元素,点击提交不会触发计算逻辑。 valAsNumber未用let/var声明,会成为全局变量,存在作用域污染风险。shippingCost是在点击事件回调内部声明的局部变量,外部代码无法访问,会导致formatter.format(shippingCost)报错。- HTML中缺少
id="finalQuote"的元素,无法显示计算出的运费结果。 - 单选按钮的
id重复(如两个preferredCustomer),违反HTML规范,会导致标签与输入框的关联异常。 - 提交按钮绑定了
onclick="AddQuote()",但JS中未定义该函数,会触发额外错误。
修复后的完整代码
修复后的JavaScript代码
$(document).ready(function() { let fnum = 0, snum = 0, valAsNumber = 0; // 提前声明变量,避免全局污染 // 监听Preferred Customer单选按钮变化 $('input[name="fnum"]').on("click", function() { fnum = parseFloat($('input[name="fnum"]:checked').val()); }); // 监听Trusted Traveler单选按钮变化 $('input[name="snum"]').on("click", function() { snum = parseFloat($('input[name="snum"]:checked').val()); }); // 监听购买金额输入变化 let purchaseAmount = document.querySelector('#purchaseAmount'); purchaseAmount.addEventListener('input', function() { // 处理空值或非数字输入,默认设为0 valAsNumber = parseFloat(purchaseAmount.value) || 0; }); // 绑定提交按钮点击事件(匹配a标签的id) $("#btnSubmit").on('click', function(e) { e.preventDefault(); // 阻止a标签默认跳转行为 var boundaryValue1 = 24.99; var boundaryValue2 = 49.99; var shippingSubCost = 0; // 根据购买金额计算基础运费 if (valAsNumber <= boundaryValue1) { shippingSubCost = 5.00; } else if (valAsNumber > boundaryValue1 && valAsNumber <= boundaryValue2) { shippingSubCost = 2.50; } else { shippingSubCost = 0.00; } // 计算最终运费 var shippingCost = (shippingSubCost * fnum) + (valAsNumber * snum); const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); var outputShippingCost = formatter.format(shippingCost); // 打印调试信息 console.log("Shipping Cost = " + outputShippingCost); console.log("Purchase Amount = $" + valAsNumber.toFixed(2)); console.log("shippingSubFee = $" + shippingSubCost.toFixed(2)); console.log("preferredCustomer multiplier = " + fnum); console.log("trustedTraveler multiplier = " + snum); // 将结果显示到页面 $("#finalQuote").val(outputShippingCost); }); });
修复后的HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> <a class="navbar-brand" href="index.html">Get your Shipping Quote Now!</a> <div class="collapse navbar-collapse" id="navbarsExampleDefault"> <ul class="navbar-nav mr-auto"> <li class="nav-item"> <a class="nav-link" href="index.html">Home</a> </li> </ul> </div> </nav> <main role="main" class="container" style="padding-top: 5em"> <h1 style="text-align: center;">Enter Information</h1> <form id="addForm" name="addForm"> <div class="form-group"> <div class="card"> <div class="card-header"> <b>Customer Information</b> </div> <div style="padding: 10px"> <div class="form-group"> <label for="firstName">First Name</label> <input type="text" class="form-control" id="firstName" name="firstName"> </div> <div class="form-group"> <label for="lastName">Last Name</label> <input type="text" class="form-control" id="lastName" name="lastName"> </div> <div class="form-group"> <label for="address">Address</label> <input type="text" class="form-control" id="address" name="address"> </div> <div class="form-row"> <div class="form-group col-md-6"> <label for="city">City</label> <input type="text" class="form-control" id="city" name="city"> </div> <div class="form-group col-md-4"> <label for="province">Province</label> <select id="province" class="form-control" name="province"> <option value="ON" selected>ON</option> <option value="NL">NL</option> <option value="PE">PE</option> <option value="NS">NS</option> <option value="NB">NB</option> <option value="QC">QC</option> <option value="MB">MB</option> <option value="SK">SK</option> <option value="AB">AB</option> <option value="BC">BC</option> <option value="YT">YT</option> <option value="NT">NT</option> <option value="NU">NU</option> </select> </div> <div class="form-group col-md-2"> <label for="postalCode">Postal Code</label> <input type="text" class="form-control" id="postalCode" name="postalCode"> </div> </div> <div class="form-row"> <div class="form-group col-md-4"> <label for="phone">Phone Number</label> <input type="text" class="form-control" id="phone" name="phone"> </div> <div class="form-group col-md-8"> <label for="email">Email address</label> <input type="email" class="form-control" id="email" name="email"> </div> </div> </div> </div> <br> <div class="card"> <div class="card-header"> <b>Customer Purchasing Information</b> </div> <div class="card-body"> <div id="optionfood"> <div class="form-group"> <label>Are you a Preferred Customer?</label> <input type="radio" id="preferredCustomerYes" name="fnum" value="0">Yes <input type="radio" id="preferredCustomerNo" name="fnum" value="1" checked>No <br> </div> <div class="form-group"> <label>Are you a Trusted Traveler?</label> <input type="radio" id="trustedTravelerYes" name="snum" value="0" checked>Yes <input type="radio" id="trustedTravelerNo" name="snum" value="0.15">No <br> </div> <div class="form-group"> <label for="purchaseAmount">Purchase Amount ($CDN)</label> <input type="number" class="form-control" name="purchaseAmount" id="purchaseAmount" step="0.01" value="" placeholder="$0.00" min="0.01"> </div> <!-- 添加显示运费的输入框 --> <div class="form-group"> <label for="finalQuote">Calculated Shipping Cost (USD)</label> <input type="text" class="form-control" id="finalQuote" readonly> </div> </div> </div> </div> </div> <a type="button" class="btn btn-primary" id="btnSubmit" style="color: white">Submit</a> </form> </main> </body>
内容的提问来源于stack exchange,提问作者bob524
相关产品推荐
相关产品推荐

