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

tjcombo
  • 43
  • 1
  • 1
  • 5

5 Answers5

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';
});
lostsource
  • 21,070
  • 8
  • 66
  • 88
  • WoW I was looking for a way to find the current index in a set of elements through vanilla JS. I stumbled upon http://stackoverflow.com/a/1933609/1606729 but I wouldn't have written such a good answer – koopajah Dec 01 '12 at 10:10
  • 1
    .. and I just found out what Vanilla JS is – lostsource Dec 01 '12 at 10:36
  • I was really wondering what was not "vanilla" in your example ^^ Glad he accepted your answer in the end! – koopajah Dec 01 '12 at 10:39
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>
Bruno
  • 5,961
  • 6
  • 33
  • 52
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/

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
koopajah
  • 23,792
  • 9
  • 78
  • 104
  • 1
    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. – koopajah Dec 01 '12 at 10:00
  • since i think he only used javascript tag – NullPoiиteя Dec 01 '12 at 10:01
  • 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. – koopajah Dec 01 '12 at 10:03
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.

  • Hi Afdhal, and welcome to Stack Overflow! Can you provide a brief explanation of how/why this works, beyond just providing the code? Thanks! – Max von Hippel Dec 26 '18 at 05:03
  • 1
    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. – Afdhal Atiff Tan Dec 27 '18 at 01:48
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

OPTIMUS PRIME
  • 1,297
  • 9
  • 20