【问题标题】:Is there a way to select index of an array element on click?有没有办法在点击时选择数组元素的索引?
【发布时间】:2019-10-20 13:41:41
【问题描述】:

我正在努力在单击时选择数组内元素的特定索引。这是代码的和平,提前感谢!

<div>

 <span class="dot"></span>
 <span class="dot"></span> -- lets say we click on this span
 <span class="dot"></span>
 <span class="dot"></span>
 <span class="dot"></span>

</div>



var dots = document.querySelectorAll(".dot");
for(var i = 0; i < dots.length; i ++){
dots[i].addEventListener("click", function(){
console.log(this) -- prints the actual html <span class="dot"></span>

// ?? How to print index of an element? To be more specific, in this case 
just "1" ??

})
}

【问题讨论】:

    标签: javascript html arrays indexof


    【解决方案1】:

    实现此目的的一种方法是向您的 dots 添加一个属性(我将其命名为 dotIndex),然后 console.log 这个属性。

    var dots = document.querySelectorAll(".dot");
    
    for(var i = 0; i < dots.length; i ++){
        dots[i].dotIndex = i;
        dots[i].addEventListener("click", function(){
            console.log(this.dotIndex);
        })
    }
    

    检查小提琴:https://jsfiddle.net/254uqtm0/

    但是,正如 Ori Drori 建议的那样,您只需在循环中将 var 更改为 let 即可。如果您对原因感到困惑,请查看此线程:What's the difference between using "let" and "var"?

    【讨论】:

    • 请注意,这样做时,如果点数发生变化,您需要更新索引
    • 谢谢大家!并特别感谢您!我什至没有想到自定义属性。一切顺利! :)
    【解决方案2】:

    由于您为每个元素添加了一个事件侦听器,因此您可以 console.log 记录i 的值。

    注意:我在 for 循环中使用 let i 而不是 var i,因为 let 使 i 作用域为被阻止,这保留了当前的 i 值事件处理程序。

    const dots = document.querySelectorAll(".dot");
    for (let i = 0; i < dots.length; i++) {
      dots[i].addEventListener("click", function() {
        console.log({ i });
      })
    }
    <div>
    
      <span class="dot">1</span>
      <span class="dot">2</span>
      <span class="dot">3</span>
      <span class="dot">4</span>
      <span class="dot">5</span>
    
    </div>

    【讨论】:

    • 您可能想解释一下,您的代码和 OP 的代码之间的一个关键区别是使用 let 而不是 var,以及为什么您的答案只适用于前者。
    • 对,你是@Utkanos。
    【解决方案3】:

    你可以这样做

    const spans = [...document.getElementsByClassName('dot')];
    spans.forEach(i => i.addEventListener('click', () => console.log(spans.indexOf(i))));
    

    【讨论】:

      【解决方案4】:

      您只需要一个事件侦听器 (event delegation)。处理程序可以遍历现有元素并使用它的索引做一些事情。比如:

      const log = (...things) => { 
        console.clear(); 
        things.forEach(thing => console.log(thing))
      };
      
      // iterate within the handler
      document.addEventListener("click", showIndex);
      
      // alternative: add a dataset value to the elements on page load
      // and make the handler do something with that. This is static and
      // can't be used if the number of .dott-elements changes dynamcally
      Array.from(document.querySelectorAll(".dott")).forEach( (el, i) => el.dataset.index = i);
      document.addEventListener("click", alternativeShowIndex);
      
      function showIndex(evt) {
        if (evt.target.matches(".dot")) {
          let currentDot = {};
          const allDots = Array.from(document.querySelectorAll(".dot"));
          for (let i = 0; i < allDots.length; i += 1) {
            if (allDots[i] === evt.target) {
              currentDot = {index: i, text: allDots[i].textContent};
              break;
            }
          }
          log(currentDot);
        }
      }
      
      function alternativeShowIndex(evt) {
        evt.target.matches(".dott") && log(evt.target.dataset.index);
      }
      <div>
       <span class="dot">first</span>
       <span class="dot">second</span>
       <span class="dot">third</span>
       <span class="dot">fourth</span>
       <span class="dot">fifth</span>
      </div>
      
      <div>
       <span class="dott">alt-first</span>
       <span class="dott">alt-second</span>
       <span class="dott">alt-third</span>
       <span class="dott">alt-fourth</span>
       <span class="dott">alt-fifth</span>
      </div>

      【讨论】:

      • 你可以用event.target.matches('.dot')代替evt.target.classList.contains("dot")
      • @OriDrori 当然,改变它。虽然classList.contains 可能更容易解释。
      • 任何对你有用的东西。我更喜欢matches,因为它在使用事件委托时对更广泛的选择器很有用。
      【解决方案5】:

      你可以这样做

      var dots = [...document.getElementsByClassName('dot')];
      
      for (let i=0; i<dots.length; i++) {
      	dots[i].addEventListener("click", () => {
        	console.log(i);
        });
      }
      <div>
         <span class="dot">0</span>
         <span class="dot">1</span> 
         <span class="dot">2</span>
         <span class="dot">3</span>
         <span class="dot">4</span>
      </div>

      【讨论】:

        猜你喜欢
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        相关资源
        最近更新 更多