4

I have 3 divs with class: wpEdit and onClick: alertName()

<div class="wpEdit" onClick="alertName()">Bruce Lee</div>
<div class="wpEdit" onClick="alertName()">Jackie Chan</div>
<div class="wpEdit" onClick="alertName()">Jet li</div>

When clicked i want to know the Index of class wpEdit of the clicked Div:

function alertName(){
    //Something like this
    var classIndex = this.className.index; // This obviously dosnt work
    alert(classIndex); 
}

when clicked on Bruce Lee it should alert : 0 when clicked on Jackie Chan it should alert : 1 when clicked on Jet Li it should alert : 2

I need to know which instance of class="wpEdit" is clicked on

1
  • i want to do it by pure js, but if not jQuery is cool Commented Dec 1, 2012 at 10:20

5 Answers 5

5

Try this

function clickedClassHandler(name,callback) {

    // apply click handler to all elements with matching className
    var allElements = document.body.getElementsByTagName("*");

    for(var x = 0, len = allElements.length; x < len; x++) {
        if(allElements[x].className == name) {
            allElements[x].onclick = handleClick;
        }
    }

    function handleClick() {
        var elmParent = this.parentNode;
        var parentChilds = elmParent.childNodes;
        var index = 0;

        for(var x = 0; x < parentChilds.length; x++) {
            if(parentChilds[x] == this) {
                break;
            }

            if(parentChilds[x].className == name) {
                index++;
            }
        }

        callback.call(this,index);
    }
}

Usage:

clickedClassHandler("wpEdit",function(index){
    // do something with the index
    alert(index);

    // 'this' refers to the element 
    // so you could do something with the element itself
    this.style.backgroundColor = 'orange';
});
Sign up to request clarification or add additional context in comments.

3 Comments

WoW I was looking for a way to find the current index in a set of elements through vanilla JS. I stumbled upon stackoverflow.com/a/1933609/1606729 but I wouldn't have written such a good answer
.. and I just found out what Vanilla JS is
I was really wondering what was not "vanilla" in your example ^^ Glad he accepted your answer in the end!
2

The first thing you might want to address in your code is the inline HTML binding.

You could use document.addEventListener on each element, or rely on event delegation.

The widely most used implementation of event delegation comes with jQuery. If you're already using jQuery, this is the way to go!

Alternatively I've also my own little delegate utility.

const delegate = (fn, selector) => {
  return function handler(event) {
    const matchingEl = matches(event.target, selector, this);
    if(matchingEl != null){
      fn.call(matchingEl, event);
    }
  };
};

const matches = (target, selector, boundElement) => {
  if (target === boundElement){
    return null;
  }
  if (target.matches(selector)){
    return target;
  }
  if (target.parentNode){
    return matches(target.parentNode, selector, boundElement);
  }
  return null;
};

This is how you would register the event listener.

document.getElementById('#parent')
  .addEventListener('click', delegate(handler, '.wpEdit'));

And this is how you could get the index of the element that generated the event.

const handler = (event) => {
  console.log(Array.prototype.indexOf.call(event.currentTarget.children, event.target));
}

Live demo:

const delegate = (fn, selector) => {
  return function handler(event) {
    const matchingEl = matches(event.target, selector, this);
    if (matchingEl != null) {
      fn.call(matchingEl, event);
    }
  };
};

const matches = (target, selector, boundElement) => {
  if (target === boundElement) {
    return null;
  }
  if (target.matches(selector)) {
    return target;
  }
  if (target.parentNode) {
    return matches(target.parentNode, selector, boundElement);
  }
  return null;
};

const handler = (event) => {
  console.log(Array.prototype.indexOf.call(event.currentTarget.children, event.target));
}

document.getElementById('parent')
  .addEventListener('click', delegate(handler, '.wpEdit'));
<div id="parent">
  <div class="wpEdit">Bruce Lee</div>
  <div class="wpEdit">Jackie Chan</div>
  <div class="wpEdit">Jet li</div>
</div>

1 Comment

jQuery would be the easiest way to accomplish this.
1

If you want the index of the div's based on your class wpEdit you can do like this:

HTML:

<div class="wpEdit">Bruce Lee</div>
<div class="wpEdit">Jackie Chan</div>
<div class="other">Other</div>
<div class="wpEdit">Jet li</div>

JS:

$(".wpEdit").bind("click", function(){
    var divs = $(".wpEdit");
    var curIdx = divs.index($(this));

    alert(curIdx);
});

Live example : http://jsfiddle.net/pJwzc/

More information on the index function of jQuery : http://api.jquery.com/index/

3 Comments

No one mentionned explicitely "I want to do this in pure javascript" either. I don't see the problem in giving a working answer, I don't know how to do this in pure javascript but I'm searching.
since i think he only used javascript tag
He might have only used javascript tags because he doesn't even know about jQuery. I explained I'm using jQuery and gave a link to the function.
0

Using vanilla javascript, this one works for me:

var wpEdits = document.querySelectorAll(".wpEdit");

for (let i = 0; i < wpEdits.length; i++)
  wpEdits[i].addEventListener("click", showID);

function showID(evt) {
  for (let i = 0; i < wpEdits.length; i++)
    if(wpEdits[i] == evt.target)    
      alert(i);
}

May not be the best solution though as I am still new to js.

Since I am very new to JS, take the following explanation with a grain of salt:

(Line-1) This is similar to var wpEdits = document.getElementsByClassName("wpEdit");. It will assign all instances of class="wpEdit" from the html file to the wpEdits variable.

(Line-3 and Line-4) This two lines will cause any click on the class="wpEdit" to call function showID() defined below.

(Line-6 and Line-10) When a click event happens, the browser will pass the unique properties of the item being clicked to the evt variable. This then is used in the for loop to compare against all available instances incrementally. The evt.target is used to get to the actual target. Once a match is found, it will alert the user.

To avoid wasting CPU time, running a break; is recommended to exit the loop soon after the match is found.

2 Comments

Hi Afdhal, and welcome to Stack Overflow! Can you provide a brief explanation of how/why this works, beyond just providing the code? Thanks!
Thank you for the warm welcome @MaxvonHippel ! Forgive me for not explaining the code. I am very new to JS and I don't think I am qualified to explain it as I worry it might confuse others. I will do my best to explain it this time.
0

I could not understand, why people add new functions in previous answers, so...

const wpEdit = document.getElementsByClassName('wpEdit');
for(let i = 0; i < wpEdit.length; i++){
  wpEdit[i].addEventListener('click',function(){
    alert(i);
  });
}

I just added 'click' event, using the loop. And [i] already is the current clicked class index...

FIDDLE

Comments

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.