javascript - 如何查找和修复未定义属性的类型错误
问题描述
我正在关注一个关于填字游戏的教程,但是在我selectLetter()
通过按键触发该功能后,当我在 chrome 中运行它时收到此消息:
“未捕获的类型错误:无法读取
'clueA'
未定义的属性”*
当我在 Firefox 开发人员中运行它时,这条消息:
“
currentLetter.dataset
类型错误:未定义”。*
我尝试在 console.log 中使用 typeof 来跟踪 currentLetter 和 currentLetter.dataset 的值,但这让我更加困惑。
var allLetters;
var currentLetter;
var wordLetters;
var acrossClue;
var downClue;
var typeDirection = "right";
window.onload = init;
function init() {
allLetters = document.querySelectorAll("table#crossword span");
currentLetter = allLetters[0];
var acrossID = currentLetter.dataset.clueA;
var downID = currentLetter.dataset.clueD;
acrossClue = document.getElementById(acrossID);
downClue = document.getElementById(downID);
formatPuzzle(currentLetter);
for (var i = 0; i < allLetters.length; i++) {
allLetters[i].style.cursor = "pointer";
allLetters[i].onmousedown = function(e) {
formatPuzzle(e.target);
}
}
document.onkeydown = selectLetter;
console.log("----init function----\n" + "Current Letter Type: " + typeof currentLetter + " \ncurrentLetter.dataset Type: " + typeof currentLetter.dataset);
}
function formatPuzzle(puzzleLetter) {
currentLetter = puzzleLetter;
for (var i = 0; i < allLetters.length; i++) {
allLetters[i].style.backgroundColor = "";
}
acrossClue.style.color = "";
downClue.style.color = "";
if (currentLetter.dataset.clueA !== undefined) {
acrossClue = document.getElementById(currentLetter.dataset.clueA);
acrossClue.style.color = "blue";
wordLetters = document.querySelectorAll("[data-clue-a=" + currentLetter.dataset.clueA + "]");
for (i = 0; i < wordLetters.length; i++) {
wordLetters[i].style.backgroundColor = "rgb(231,231,255)";
}
}
if (currentLetter.dataset.clueD !== undefined) {
downClue = document.getElementById(currentLetter.dataset.clueD);
downClue.style.color = "red";
wordLetters = document.querySelectorAll("[data-clue-d=" + currentLetter.dataset.clueD + "]");
for (i = 0; i < wordLetters.length; i++) {
wordLetters[i].style.backgroundColor = "rgb(255,231,231)";
}
}
if (typeDirection === "right") {
currentLetter.style.backgroundColor = "rgb(191,191,255)";
} else {
currentLetter.style.backgroundColor = "rgb(255,191,191)";
}
console.log("----formatPuzzle function----\n" + "Current Letter Type: " + typeof currentLetter + " \ncurrentLetter.dataset Type: " + typeof currentLetter.dataset);
}
function selectLetter(e) {
var leftLetter = currentLetter.dataset.left;
var upLetter = currentLetter.dataset.up;
var rightLetter = currentLetter.dataset.right;
var downLetter = currentLetter.dataset.down;
var userKey = e.keyCode;
console.log("----selectLetter function----\n" + "Current Letter Type: " + typeof currentLetter + " \ncurrentLetter.dataset Type: " + typeof currentLetter.dataset + "\n.dataset.up:" + currentLetter.dataset.up + "\nkeycode:" + userKey);
if (userKey === 37) {
formatPuzzle(leftLetter);
} else if (userKey === 38) {
formatPuzzle(upLetter);
} else if (userKey === 39) {
formatPuzzle(rightLetter);
} else if ((userKey === 40) || (userKey === 13)) {
formatPuzzle(downLetter);
} else if ((userKey === 8) || (userKey === 46)) {
currentLetter.textContent = "";
} else if (userKey === 32) {
switchTypeDirection;
} else if (65 <= userKey <= 90) {
currentLetter.textContent = getChar(userKey);
if (typeDirection === "right") {
formatPuzzle(rightLetter);
} else {
formatPuzzle(downLetter);
}
}
e.preventDefault();
}
function switchTypeDirection() {
}
function getChar(keyNum) {
return String.fromCharCode(keyNum);
}
<table id="crossword">
<caption>Today's Crossword</caption>
<tr>
<td><span id="c1_1" data-letter="C" data-right="c1_2" data-left="c1_8" data-down="c2_1" data-up="c11_1" data-clue-a="a1" data-clue-d="d1"></span><sup>1</sup></td>
<td><span id="c1_2" data-letter="A" data-right="c1_3" data-left="c1_1" data-down="c2_2" data-up="c11_2" data-clue-a="a1" data-clue-d="d2"></span><sup>2</sup></td>
<td><span id="c1_3" data-letter="M" data-right="c1_4" data-left="c1_2" data-down="c2_3" data-up="c11_3" data-clue-a="a1" data-clue-d="d3"></span><sup>3</sup></td>
<td><span id="c1_4" data-letter="O" data-right="c1_5" data-left="c1_3" data-down="c2_4" data-up="c10_4" data-clue-a="a1" data-clue-d="d4"></span><sup>4</sup></td>
<td><span id="c1_5" data-letter="M" data-right="c1_6" data-left="c1_4" data-down="c2_5" data-up="c11_5" data-clue-a="a1" data-clue-d="d5"></span><sup>5</sup></td>
<td><span id="c1_6" data-letter="I" data-right="c1_7" data-left="c1_5" data-down="c2_6" data-up="c11_6" data-clue-a="a1" data-clue-d="d6"></span><sup>6</sup></td>
<td><span id="c1_7" data-letter="L" data-right="c1_8" data-left="c1_6" data-down="c2_7" data-up="c11_7" data-clue-a="a1" data-clue-d="d7"></span><sup>7</sup></td>
<td><span id="c1_8" data-letter="E" data-right="c1_1" data-left="c1_7" data-down="c2_8" data-up="c11_8" data-clue-a="a1" data-clue-d="d8"></span><sup>8</sup></td>
<td class="blank"></td>
</tr>
我希望箭头键可以更改箭头键在拼图中指向的单元格的背景颜色 rgb(191,191,255),但代码停止运行,并且控制台打印了一个类型错误。
解决方案
该错误意味着currentLetter
分配了一个不是 DOM 元素的值(因为每个 DOM 元素都有一个dataset
属性)。
您分配到的唯一地方currentLetter
是init
:
currentLetter = allLetters[0];
和formatPuzzle
:
currentLetter = puzzleLetter;
allLetters[0]
将是一个 DOM 元素。
puzzleLetter
是 的参数formatPuzzle
,所以让我们看看函数是否被调用并传递了一些不是DOM 元素的东西。
在selectLetter
您formatPuzzle
使用不同的参数多次调用时,但它们都不是 DOM 元素。例如leftLetter
是 的值currentLetter.dataset.left
。
也许你打算做
var leftLetter = documnent.getElementById(currentLetter.dataset.left);
// etc
?
确保只将 DOM 元素传递给函数,并尽可能避免使用全局变量。
推荐阅读
- ios - 如何从我的 iOS 应用程序实现 Google Home 帐户同步?
- node.js - MongoDB学生考勤系统
- python - 从 C++ 返回的多维数组在使用 ctypes 时会发送垃圾
- c# - C#:编辑包含 int 的 DataTable 的一行
- c++ - 我包括
但得到未知类型名称“迭代器” - javascript - python struct.pack 等价于纯 javascript
- python - 如何获取内部值以用作 gdb 漂亮打印的数组?
- python - 在 Python 中使用 Pandas 处理嵌套的 JSON 数据
- ruby - 普通 Ruby:仅为 DateTime 实例设置时区
- javascript - javascript函数不显示html表