开发者问题收集

为什么 js 中的 getAttribute() 会出错:?

2022-07-01
86

以下是我编写的代码。 如果我将 for 循环中的代码更改为 i<len-1,那么除了最后一个链接外,它都可以正常工作 但如果我将其保留为 i<len,它就不会对任何链接起作用。

const allLists = document.querySelectorAll("a:link");
var len = allLists.length;

for (var i = 0; i < len; i++) {
  allLists[i].addEventListener("click", function (e) {
    e.preventDefault();
    const href = allLists[i].getAttribute("href");
    console.log(href);
    if (href == "#") {
      window.scrollTo({
        top: 0,
        behavior: "smooth",
      });
    }
  });
}

错误: script.js:33 未捕获 TypeError:无法读取 HTMLAnchorElement 中未定义的属性(读取“getAttribute”)。

2个回答

因为在循环之后 i 变量的大小为 len

然后,每次调用 click 事件时,要运行的代码将始终是:

const href = allLists[len].getAttribute("href");

此问题是一个 closure 问题,您可以在 此处 查看更多信息>

修改后的代码将如下所示:(将 var 更改为 let

const allLists = document.querySelectorAll("a:link");
var len = allLists.length;

for (let i = 0; i < len; i++) {
  allLists[i].addEventListener("click", function (e) {
    e.preventDefault();
    const href = allLists[i].getAttribute("href");
    console.log(href);
    if (href == "#") {
      window.scrollTo({
        top: 0,
        behavior: "smooth",
      });
    }
  });
}
<a href="1">1</a>
<a href="2">2</a>
<a href="3">3</a>
<a href="4">4</a>
Xupitan
2022-07-01

正如 Mozilla 开发者文档 中所述,“ querySelectorAll() 的行为与大多数常见的 JavaScript DOM 库不同,这可能会导致意外结果。”

因此,我建议遵循文档并编写“forEach”循环而不是“for”循环。

Casper Kuethe
2022-07-01