单击 HTML 集合中的元素时,如何使用 javascript 获取该元素的索引

How to get the index of an element in a HTML collection when that element is clicked, using javascript

我的 HTML 文件中有五个按钮。

鉴于它们是五个,我希望能够打印 HTML 集合中已单击的特定按钮的索引。即点击 btn 4 我应该看到 3 打印出来。我尝试将一些我认为可以做到的 javascript 行放在一起,但没有成功。 JS代码为:

if (document.readyState == 'loading') {
        document.addEventListener('DOMContentLoaded',execute);
    }else{
        execute()
    }
    function execute() {
        var btns = document.getElementsByClassName('item');
        for (var i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click',btnClicked);
        }       
    }
    function btnClicked(event,btns) {
        var btn = event.currentTarget;
        var btnIndex = btns.indexOf(btn)
        console.log(btnIndex)
    }
<body>
        <div class="btn-items">
            <button class="item">btn 1 </button>
            <button class="item">btn 2 </button>
            <button class="item">btn 3</button>
            <button class="item">btn 4</button>
            <button class="item">btn 5</button> 
        </div>
    </body>

要走的路是什么?

您可以使用 HTML 元素上的 setAttribute 函数为每个按钮指定一个自定义属性。然后您只需要使用 getAttribute 函数检索此属性的值。请参阅下面的代码示例:

var btns = document.getElementsByClassName('item')

for (var i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', btnClicked)
    btns[i].setAttribute('data-index', i)
}

function btnClicked(event) {
   var btn = event.currentTarget;
   console.log(btn.getAttribute('data-index'))
}
<div class="btn-items">
    <button class="item">btn 1 </button>
    <button class="item">btn 2 </button>
    <button class="item">btn 3</button>
    <button class="item">btn 4</button>
    <button class="item">btn 5</button> 
</div>

document.getElementsByClassName() returns 没有 indexOf() 功能的 node list(see this question)

您可以将 i 作为参数传递给 btnClicked()

var btns;
if (document.readyState == 'loading') {
        document.addEventListener('DOMContentLoaded',execute);
    }else{
        execute()
    }
    function execute() {
        btns = document.getElementsByClassName('item');
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click',(e)=> btnClicked(e,i));
        }       
    }
    function btnClicked(event,i) {
        
        console.log(i)
    }

您可以使用此解决方案获得所需的输出

function execute() {
    var btns = document.querySelectorAll('.item');
    btns.forEach(btnClicked);
  
}
function btnClicked(btn,index) {
    btn.addEventListener('click',()=>{
       console.log(index)
    });
}

这是一种更简洁的实现方式。

为什么不使用

if (document.readyState == 'loading') {
    document.addEventListener('DOMContentLoaded',execute);
}else{
    execute();
}
function execute() {
    const btns = document.getElementsByClassName('item');
    for(let i = 0; i < btns.length; i++){
        btns[i].addEventListener('click',function(){
            console.log('button index : '+i);
        });
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="item">button 1</button>
    <button class="item">button 2</button>
    <button class="item">button 3</button>
    <script src="script.js"></script>
</body>
</html>

通常当您想将同一事件应用于多个元素时,请尝试使用事件委托。

基本上你所做的是监听父级 btn-items 上的事件,这是有效的,因为浏览器冒泡事件。

下面是一个示例,请注意,因为您监听父级上的所有点击,如果您点击按钮之间的间隙,您将获得 -1,在真实示例中,您可能需要处理此问题。

但这种方法的优点是只有一个事件侦听器和一个事件回调。一个非常好的优点是,如果您以后动态添加 .item,它也会自动为这些工作。

const btns = document.querySelector('.btn-items');
btns.addEventListener('click', e => {
  console.log([...btns.children].
    indexOf(e.target));
});
<div class="btn-items">
    <button class="item">btn 1 </button>
    <button class="item">btn 2 </button>
    <button class="item">btn 3</button>
    <button class="item">btn 4</button>
    <button class="item">btn 5</button> 
</div>