JavaScript报错:Cannot read properties of null (reading 'value') 求助
问题:计算器开发中的Null TypeError问题
错误信息
Uncaught TypeError: Cannot read properties of null (reading 'value')
问题说明
开发设计感计算器时出现上述错误,发现代码中提前获取的display元素为null,但将所有display替换为document.getElementById('display')后可正常运行,无法定位问题根源。
代码示例
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Calculator</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css"> </head> <script src="index.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" integrity="sha256-qM7QTJSlvtPSxVRjVWNM2OfTAz/3k5ovHOKmKXuYMO4=" crossorigin="anonymous"></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script> <body> <div class="d-flex flex-column justify-content-center w-100 h-100"> <div class="container-white"> <div class="d-flex flex-column justify-content-center align-items-center"> <h1>Calculator</h1> <div class="calc-main"> <input type="text" id='display'> <div class="calc-basic input-group"> <input type="button" value="1" class="btn numbers" onclick="insert('1');"> <input type="button" value="2" class="btn numbers" onclick="insert('2');"> <input type="button" value="3" class="btn numbers" onclick="insert('3');"> <input type="button" value="+" class="btn operators" onclick="insert('+');"> <input type="button" value="=" class="btn functions" onclick="equals();"> </div> <br> <div class="calc-basic btn-group"> <button class="btn numbers" onclick="insert('4');">4</button> <button class="btn numbers" onclick="insert('5');">5</button> <button class="btn numbers" onclick="insert('6');">6</button> <button class="btn operators" onclick="insert('-');">-</button> <button class="btn operators" onclick="divide()">/</button> </div> <br> <div class="calc-basic btn-group"> <button class="btn numbers" onclick="insert('7');">7</button> <button class="btn numbers" onclick="insert('8');">8</button> <button class="btn numbers" onclick="insert('9');">9</button> <button class="btn operators" onclick="multiply();">*</button> <button class="btn numbers" onclick="insert('.');">.</button> </div> <br> </div> </div> </div> </div> </body> </html>
JavaScript代码
let display = document.getElementById('display'); let buttons = document.getElementsByClassName("button"); function insert(sym) { display.value += sym; } function equals() { if ((display.value).indexOf("^") > -1 ) { let base = (display.value).slice(0, (display.value).indexOf("^")); let exponent = (display.value).slice((display.value).indexOf("^") + 1 ); display.value = eval("Math.pow(" + base + "," + exponent + ")"); } else { display.value = eval(display.value) } } function multiply() { display.value += "*"; } function divide() { display.value += "/"; }
问题根源及解决方案
根源
你的index.js脚本被放在了<head>标签内,浏览器解析HTML是从上到下执行的,这时候<body>里的#display元素还没有被渲染出来,document.getElementById('display')自然返回null,后续函数调用display.value就会触发错误。
而直接在函数里用document.getElementById('display')能正常运行,是因为函数是在按钮点击时才执行,此时整个DOM已经加载完成,每次调用都能正确获取到元素。
解决方案
有两种常用的修复方式:
- 调整脚本加载位置
把<script src="index.js"></script>移动到<body>标签的末尾,</body>之前,确保DOM完全加载后再执行JS代码:
<!-- 其他代码 --> </div> <script src="index.js"></script> </body> </html>
- 使用DOM加载完成事件
在JS代码中用DOMContentLoaded事件包裹元素获取和函数定义,确保代码在DOM加载完成后执行:
document.addEventListener('DOMContentLoaded', function() { let display = document.getElementById('display'); window.insert = function(sym) { display.value += sym; }; window.equals = function() { if ((display.value).indexOf("^") > -1 ) { let base = (display.value).slice(0, (display.value).indexOf("^")); let exponent = (display.value).slice((display.value).indexOf("^") + 1 ); display.value = eval("Math.pow(" + base + "," + exponent + ")"); } else { display.value = eval(display.value) } }; window.multiply = function() { display.value += "*"; }; window.divide = function() { display.value += "/"; }; });
这样就能保证display变量正确获取到DOM元素,避免null错误。
内容的提问来源于stack exchange,提问作者Thanasis Lanaras
相关产品推荐
相关产品推荐

