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