JS记忆游戏checkMatch函数报Cannot set properties of null错误
记忆游戏匹配后更新得分时报TypeError问题
问题表现
- 预期逻辑:点击两张卡牌完成匹配判断后,页面自动更新显示当前得分
- 实际运行抛出错误:
Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
报错抛出位置:checkMatch函数
- 前期排查:已全面检查代码拼写未发现异常,检索同类问题未找到适配解决方案。

附完整问题代码
JavaScript代码
document.addEventListener('DOMContentLoaded', () => { const cardArray = [{ name: 'fries', img: 'images/fries.png' }, { name: 'cheeseburger', img: 'images/cheeseburger.png' }, { name: 'ice-cream', img: 'images/ice-cream.png' }, { name: 'pizza', img: 'images/pizza.png' }, { name: 'milkshake', img: 'images/milkshake.png' }, { name: 'hotdog', img: 'images/hotdog.png' }, { name: 'fries', img: 'images/fries.png' }, { name: 'cheeseburger', img: 'images/cheeseburger.png' }, { name: 'ice-cream', img: 'images/ice-cream.png' }, { name: 'pizza', img: 'images/pizza.png' }, { name: 'milkshake', img: 'images/milkshake.png' }, { name: 'hotdog', img: 'images/hotdog.png' } ] console.log(cardArray); cardArray.sort(() => 0.5 - Math.random()) const gridDisplay = document.querySelector('#grid') const resultDisplay = document.getElementById('#result') function createBoard() { for (let i = 0; i < cardArray.length; i++) { const card = document.createElement('img'); card.setAttribute('src', 'images/blank.png'); card.addEventListener('click', flipCard); card.setAttribute('data-id', i); console.log(card, i) gridDisplay.appendChild(card) } } let cardsChosen = []; const cardsWon = []; let cardsChosenIds = [] function checkMatch() { const card = document.querySelectorAll('img') const optionOneId = cardsChosenIds[0] const optionTwoId = cardsChosenIds[1] if (optionOneId == optionTwoId) { card[optionOneId].setAttribute('src', 'images/blank.png'); card[optionTwoId].setAttribute('src', 'images/blank.png'); alert("you selected same card twice"); } else if (cardsChosen[0] === cardsChosen[1]) { alert('You found a match') card[optionOneId].setAttribute('src', 'images/white.png') card[optionTwoId].setAttribute('src', 'images/white.png') card[optionOneId].removeEventListener('click', flipCard) card[optionTwoId].removeEventListener('click', flipCard) cardsWon.push(cardsChosen) } else { card[optionOneId].setAttribute('src', 'images/blank.png'); card[optionTwoId].setAttribute('src', 'images/blank.png'); alert("you selected different card. Try Again! "); } cardsChosen = [] cardsChosenIds =[] resultDisplay.innerHTML= cardsWon.length if(cardsWon.length ==(cardArray.length/2)){ resultDisplay.innerHTML = 'Congralutions you won it all' } } function flipCard() { let getid = this.getAttribute('data-id') cardsChosen.push(cardArray[getid].name) cardsChosenIds.push(getid) console.log(cardsChosen) console.log(cardsChosenIds); this.setAttribute('src', cardArray[getid].img) if (cardsChosen.length == 2) { setTimeout(checkMatch, 1100) } } createBoard() })
HTML代码
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Memory Game</title> <link rel="stylesheet" type = "text/css" href="styles.css"> </head> <body> <h3>Score : <span id ="result"></span></h3> <div id = "grid"> </div> <script script src= "neck.js"></script> </body> </html>
错误原因与修复
核心问题出在得分显示元素的获取逻辑:
- 代码里写的
const resultDisplay = document.getElementById('#result')写法错误。getElementById接收的参数是纯id字符串,不需要带CSS选择器的#前缀——#是querySelector这类走CSS选择器语法的方法才需要加的标识。多写这个#之后,浏览器会去找id值为#result的元素,和HTML里实际id为result的span标签匹配不上,拿到的resultDisplay就是null,后续执行resultDisplay.innerHTML = xxx时,自然会抛出“无法给null设置innerHTML属性”的错误。 - 修复只需要把这行代码改成
const resultDisplay = document.getElementById('result'),得分更新功能就能正常运行。
另外还有两处不影响当前报错但建议修正的小问题:
- HTML里的script标签重复写了
script属性,正确写法是<script src="neck.js"></script> - 通关提示里的
Congralutions存在拼写错误,正确拼写为Congratulations
内容的提问来源于stack exchange,提问作者rohit
相关产品推荐
相关产品推荐

