首页 > 解决方案 > eventListener 总是在第一个元素上触发

问题描述

当我单击第二个或第三个元素时,第一个元素的标签会记录到控制台。

我究竟做错了什么?

沙盒:https ://jsfiddle.net/x01e4kgu/3/

HTML

<form action="">
  <div class="input--upload">
    <label for="attachment">Upload 1</label>
    <input type="file" name="attachment[]" id="attachment">
  </div>
  <div class="input--upload">
    <label for="attachment">Upload 2</label>
    <input type="file" name="attachment[]" id="attachment">
  </div>
  <div class="input--upload">
    <label for="attachment">Upload 3</label>
    <input type="file" name="attachment[]" id="attachment">
  </div>
</form>

JS

const fileInputs = document.querySelectorAll('.input--upload input')
    fileInputs.forEach(input => {
        input.addEventListener('change', function(e) {
            const label = e.target.parentNode.querySelector('label')
            console.log(label)
        })
})

标签: javascript

解决方案


这边走

  1. ID 必须是唯一的(您的代码中不需要任何一个)您的
    所有label元素都使用for指向相同的相同属性id,所有这些都只涉及具有此属性的第一个元素id(其他元素被忽略)

  2. 用于onchange使用箭头函数,
    它允许您绕过e.target...
    ,因为它允许您停留在局部变量的范围内(实际上只inEl

<form action="">
  <div class="input--upload">
    <label>
      Upload 1
      <input type="file" name="attachment[]" >
    </label>
  </div>
  <div class="input--upload">
    <label>
      Upload 2
      <input type="file" name="attachment[]" >
    </label>
  </div>
  <div class="input--upload">
    <label >
      Upload 3
      <input type="file" name="attachment[]" ">
    </label>
  </div>
</form>
const fileInputs = document.querySelectorAll('div.input--upload input')

fileInputs.forEach( inEl =>
  {
  inEl.onchange = e =>
    {
    let el_Lb = inEl.closest('label')
    console.log( el_Lb.textContent )
    }
  })

推荐阅读