get index of class element with inline onclick - p

2019-08-27 18:20发布

so i have some class-elements:

<span class="show" onclick="show()">show</span>
<span class="show" onclick="show()">show</span>
<span class="show" onclick="show()">show</span>

when i click one of these elements i need the index for some reason. i know how to use jQuery, but thats not what i am asking for, here.

my js function should look something like this:

function show() {
    var index = document.getElementsByClassName('show')[??];
    alert(index);
}

How is that possible with pure javascript? NOTE: i have to stick with the onclick="show()" that cannot be changed.

i hope someone can help, thanks in advance :)

4条回答
干净又极端
2楼-- · 2019-08-27 18:31

If you're JUST looking for the index, you can pass that to the show() method.

<span class="show" onclick="show(0)">show</span>
<span class="show" onclick="show(1)">show</span>
<span class="show" onclick="show(2)">show</span>
查看更多
Summer. ? 凉城
3楼-- · 2019-08-27 18:36

You can try something like this:

  • Use addEventListener to bind event handlers. This will allow you to use this.
  • If you still need index of element, you can either loop over elements or convert NodeList into array and then use Array.indexOf

Sample

Onclick

function show(self){
  var spans = document.querySelectorAll('.show');
  console.log(Array.from(spans).indexOf(self))
}
<span class="show" onclick="show(this)">show</span>
<span class="show" onclick="show(this)">show</span>
<span class="show" onclick="show(this)">show</span>

addEventListener

function show(){
  var spans = document.querySelectorAll('.show');
  console.log(Array.from(spans).indexOf(this))
}

function registerEvent(){
  var spans = document.querySelectorAll('.show');
  for(var i = 0; i< spans.length; i++){
    spans[i].addEventListener("click", show)
  }
}

registerEvent();
<span class="show" >show</span>
<span class="show" >show</span>
<span class="show" >show</span>

查看更多
做个烂人
4楼-- · 2019-08-27 18:40

If you absolutely insist on using the onclick attribute (even though you don't really need to):

// get live collection so you only need to call this once
var liveCollection = document.getElementsByClassName('show');

function show(event) {
    // convert liveCollection to array for `.indexOf()`

    // either ES6
    var shows = [...liveCollection];
    // or ES5
    var shows = Array.prototype.slice.call(liveCollection);

    var index = shows.indexOf(event.currentTarget);

    alert(index);
}
.show {
  cursor: pointer;
}
<span class="show" onclick="show(event)">show</span>
<span class="show" onclick="show(event)">show</span>
<span class="show" onclick="show(event)">show</span>

However, I would rather recommend you use delegated events to handle dynamically added elements, as using the onclick attribute is considered bad practice, but don't just take my word for it.

// see below for how to select the best container
var container = document.body;

// single event listener for all dynamically added elements
container.addEventListener('click', function (event) {
    if (event.target.classList.contains('show')) {
        show.call(event.target, event);
    }
});

// get live collection so you only need to call this once
var liveCollection = container.getElementsByClassName('show');

function show(event) {
    // convert liveCollection to array for `.indexOf()`

    // either ES6
    var shows = [...liveCollection];
    // or ES5
    var shows = Array.prototype.slice.call(liveCollection);

    // this === event.target
    var index = shows.indexOf(this);

    alert(index);
}
.show {
  cursor: pointer;
}
<span class="show">show</span>
<span class="show">show</span>
<span class="show">show</span>

The nice thing about delegated event handling is you don't need an onclick attribute to handle dynamically added elements, so this will work best for your particular usage.

It is recommended, but not necessary, that the event listener for the delegated events is attached to the most immediate container of all the dynamically added elements, so that the click event doesn't have to bubble up all the way to the document.body. This makes the handling more efficient.

查看更多
淡お忘
5楼-- · 2019-08-27 18:44

Just get the array of all the elements and find the current element who received the click

function show(el) {
  var els = Array.prototype.slice.call( document.getElementsByClassName('show'), 0 );
  console.log(els.indexOf(event.currentTarget));
}
<span class="show" onclick="show(this)">span 1</span>
<span class="show" onclick="show(this)">span 2</span>
<span class="show" onclick="show(this)">span 3</span>

查看更多
登录 后发表回答