JavaScript报错:Cannot read property 'value' of null 问题求助
Let's break down your problem and fix it step by step:
First, Understand the Root Cause of the TypeError
The error Uncaught TypeError: Cannot read property 'value' of null happens because your warning() function is trying to access .value on elements that either don't exist in your DOM or aren't loaded yet. Specifically:
document.getElementById("paid")returnsnull- Or
document.getElementById('Total')returnsnull
Since your window.onload calls TotalToPay(), which in turn calls warning(), this error fires immediately when the page loads—before those elements are available (or if they're missing entirely from your HTML).
Fix 1: Add Missing DOM Elements (or Verify Their Existence)
Looking at the HTML you shared, there are no elements with IDs paid or Total. You need to add these inputs to your form if they're supposed to exist. For example:
<!-- Add Total Amount input --> <div class="form-group"> @Html.LabelFor(model => model.Total, "Total Amount", new { @class = "control-label col-md-3" }) <div class="col-md-9"> <input type="number" class="form-control" id="Total" oninput="TotalToPay();" /> </div> </div> <!-- Add Paid Amount input --> <div class="form-group"> @Html.LabelFor(model => model.Paid, "Paid Amount", new { @class = "control-label col-md-3" }) <div class="col-md-9"> <input type="number" class="form-control" id="paid" oninput="warning();" /> </div> </div>
If these elements are dynamically added later (e.g., via AJAX), you'll need to delay calling warning() until after they're rendered.
Fix 2: Make the Radio Buttons Responsive
Your "Yes"/"No" radio buttons don't have any event listeners attached, which is why clicking them does nothing. Add an onchange handler to trigger your TotalToPay() function:
<div class="form-group"> @Html.LabelFor(model => model.Chapel, new { @class = "control-label col-md-3" }) <div class="col-md-9"> <label class="radio-inline"> @Html.RadioButtonFor(model => model.Chapel, "Yes", new { @class = "styled", @checked = true, onchange = "TotalToPay();" }) Yes </label> <label class="radio-inline"> @Html.RadioButtonFor(model => model.Chapel, "No", new { @class = "styled", onchange = "TotalToPay();" }) No </label> @Html.ValidationMessageFor(model => model.Chapel, "", new { @class = "text-danger" }) </div> </div>
Note: I fixed the @checked attribute syntax (Razor uses @checked = true, not nested htmlAttributes), and only set "Yes" as the default checked option (you can't have both radio buttons checked by default).
Fix 3: Add Robustness to Your JavaScript Functions
Prevent future errors by checking if elements exist before accessing their values, and handle non-numeric inputs gracefully:
function warning() { // Get elements first and check if they exist const paidElement = document.getElementById("paid"); const totalElement = document.getElementById('Total'); const warningElement = document.getElementById('warning'); if (!paidElement || !totalElement || !warningElement) { console.warn("Required elements not found in DOM"); return; } // Parse values, default to 0 if input is empty or non-numeric const paidAmount = parseFloat(paidElement.value) || 0; const totalAmount = parseFloat(totalElement.value) || 0; // Toggle warning visibility warningElement.style.display = paidAmount > totalAmount ? 'block' : 'none'; }
Fix 4: Ensure Code Runs After DOM is Fully Ready
While window.onload works, DOMContentLoaded triggers earlier (as soon as the DOM is built, before images/styles load) and is more reliable for static content. Replace your window.onload with:
document.addEventListener('DOMContentLoaded', function() { LoadList(); TotalToPay(); });
内容的提问来源于stack exchange,提问作者user9734038

