1

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 :)

5
  • Cant you do show(this) ? Commented May 25, 2017 at 16:41
  • You should use addEventListener. That way you will be able to use this Commented May 25, 2017 at 16:41
  • i could do show(this), but how can use that to achieve what i want? Commented May 25, 2017 at 16:42
  • i'm slightly new to programming, so my problem with the eventListener and jQuery is, that my <span> elements are generated inside an iframe during my user does something on the page. that makes is hard for me to use jQuery.click and addEventListener Commented May 25, 2017 at 16:45
  • You do not need to use onclick="show()" for dynamic elements if you use delegated event handling. See my answer for how to do this. Commented May 25, 2017 at 17:14

4 Answers 4

3

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>

Sign up to request clarification or add additional context in comments.

1 Comment

that does exactly what i want, so far. thanks for that :)
2

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>

2 Comments

thanks for helping me out, that works for me, too! i'll stick with the other answer, though, since it's a little less of code. thanks anyways!
@MaxSchlesag Thats alright. I'm glad I was able to help in any way. Have a good day. :-)
1

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.

Comments

-1

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>

1 Comment

that is not possible since the elements are generated automatically, sometimes there are a few deleted, too. so i can't set the indexes myself

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.