JavaScript for循环中的innerHTML返回为undefined

3
我一整个早上都在想这个问题。我在HTML代码中有一个包含a-j字母的列表,并希望在其中一个被点击时将其打印到控制台中。
我创建了一个for循环来查找节点列表,我可以让脚本将要点击的元素的数字打印到控制台,但是当我尝试获取innerHTML或类似内容时,它会返回未定义。
但是当我只是在控制台中输入el[3].innerHTML时,它会返回所需的字母。
请帮助我理解为什么只是因为通过for循环就使其变为未定义?
我不仅要寻找解决方案,还想了解发生这种情况的原因,以便成为更好的编码者。
谢谢!
代码:
var list = document.getElementsByTagName('ul')[0];
var el = list.getElementsByTagName('li');

for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener('click', function(f) {
    return function(event) {
      event.preventDefault();
      console.log(f.innerHTML);
    }
  }(i));
}

脚本是否在li写入页面之前的页面顶部?还要注意,字母不是元素的一部分,如果没有其他元素,您只应该看到测试节点字符串。 - Wayne
函数内可能未定义f,您能否同时放置HTML或Plunker示例以进行快速测试? - Óscar Andreu
可能是重复的问题 如何在prototype中获取单选按钮点击事件后的值 - Nikola Lukic
f === ii为整数,但其不具备该属性。 - Teemu
4个回答

1
您漏掉了变量名:

console.log(this.innerHTML);

var list = document.getElementsByTagName('ul')[0];
var el = list.getElementsByTagName('li');

console.log(el)

  for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener("click",function(f){

    return function(event){
        event.preventDefault();
        console.log(this.innerHTML);
    };
  }(i));
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>


这使整个IIFE变得不必要。 - ASDFGerte

1
当您将i作为参数传递给函数时,f的值将变为i,因此当您尝试获取f.innerHTML时,您正在尝试从整数而不是从单击的元素中获取HTML。
您可以使用this来定位单击的元素。这是一个有效的示例:

var list = document.getElementsByTagName('ul')[0];
var el = list.getElementsByTagName('li');

  for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener("click",function(f){

    return function(event){
        event.preventDefault();
        console.log(this.innerHTML);
    };
  }(i));
}
<ul>List
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

由于 @Teemu 提供了更正的信息,本文进行了编辑。


0
这是一个工作示例,我认为问题在于传递正确的元素。
var list = document.getElementsByTagName('ul')[0];
   var el = list.getElementsByTagName('li');

   for(var i = 0; i < el.length; i++ ) {
   el[i].addEventListener("click",function(e){

     return function(event){
      event.preventDefault();
      console.log(e.innerHTML);
   };
 }(el[i]));
}

0

你的主要问题

正如@teemu在评论中提到的,你的f是事件对象event。而要访问innerHtml,你需要先访问target

想法

目前你有n个<li>元素和一个eventListener。你可以只在<ul>上添加一个事件监听器,以使代码更加简洁。

代码

当你将事件监听器添加到<ul>时,你可以通过event.target访问其中的每个点击元素。

var list = document.getElementsByTagName('ul')[0];

list.addEventListener('click', logInnerHtml)

function logInnerHtml(event) {
    event.preventDefault()
    console.log(
        event.currentTarget.innerHtml
    )
}

例子

var list = document.getElementsByTagName('ul')[0];

list.addEventListener('click', logInnerHtml)

function logInnerHtml(event) {
  console.log(event.target.innerHTML)
}
<ul>
  <li>first</li>
  <li>second</li>
</ul>


嗯...事件对象是我说错了的一个错误陈述,现在已经有一个新的、更正确的评论存在了将近一个小时。 - Teemu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接