【问题标题】:I'm getting the `Cannot read property 'toggle' of undefined at HTMLLIElement.<anonymous>`我在 HTMLLIElement.<anonymous> 处收到未定义的“无法读取属性“切换”
【发布时间】:2021-05-26 09:41:27
【问题描述】:

谁能帮忙

我有一个项目列表,当我单击每个名称时,我想显示正在单击的项目的数据。

但我收到错误Uncaught TypeError: Cannot read property 'toggle' of undefined at HTMLLIElement.&lt;anonymous&gt;

如果我将forEach 应用于n.addEventListener('click'... 内的data,它可以正常工作,但它会显示所有列表的所有data,而不仅仅是我单击的那个。

这是代码:

const name = document.querySelectorAll('.name')
const data = document.querySelectorAll('.data')

name.forEach(n => {
  n.addEventListener('click', () => {
    data.classList.toggle('show')
  })
})
.data {
  display: none;
}

.show {
  display: block;
}
<ul class="list">
  <li class="name">
    <h3>Jack</h3>
    <div class="data">
      <span>Age: 18</span>
    </div>
  </li>
  <li class="name">
    <h3>Mike</h3>
    <div class="data">
      <span>Age: 19</span>
    </div>
  </li>
  <li class="name">
    <h3>Greg</h3>
    <div class="data">
      <span>Age: 17</span>
    </div>
  </li>
</ul>

【问题讨论】:

    标签: javascript html foreach addeventlistener


    【解决方案1】:

    请在下面找到解决方案。您还需要注意性能。在每个 &lt;li&gt; 上绑定事件不是一个好方法。我们可以在这里利用事件委托的概念。

    document.querySelector('.list').addEventListener('click', function (event) {
        const target = event.target;
        if (target.classList.contains('name')) {
            target.querySelector('.data').classList.toggle('show');
            return;
        }
        
        if(target.tagName.toLowerCase() === 'h3'){
        const parentLi = target.closest('li')
        parentLi.querySelector('.data').classList.toggle('show');
        }
    })
    

    【讨论】:

    • 为了保持事件委托带来的性能优势,最好避免在事件处理程序中遍历 DOM。您可以通过relying on the existing markup 进行此操作。
    【解决方案2】:

    您正在使用返回多个元素的querySelectorAll,然后尝试使用作为单个元素的属性的classList。您还需要遍历每个 .data 元素并在其上调用 classList

    name.forEach(n => {
        data.forEach(d => {
            n.addEventListener('click', () => {
                d.classList.toggle('show');
            });
        });
    });
    

    除非您希望所有 .data 元素在点击时切换它们的 show,在这种情况下您需要反转函数的嵌套:

    name.forEach(n => {
        n.addEventListener('click', () => {
            data.forEach(d => {
                d.classList.toggle('show');
            });
        });
    });
    

    【讨论】:

    • 我尝试了第二个,它切换了所有.data,我不希望这样。第一个我也试过了,结果和第二个一样
    • 该解决方案似乎是您试图实现的 - 您真正希望程序中的行为是什么?
    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 2020-05-24
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2021-03-03
    • 2022-01-02
    相关资源
    最近更新 更多