2

I need to find the number of the list element in the unordered list when clicked. How would i go about doing this without JQuery?

<ul>
    <li><span>*</span>Cat</li>
    <li><span>*</span>Dog</li>
    <li><span>*</span>Avocado</li>
</ul>

For example, clicking on 'Cat' will give me 0, clicking on 'Dog' will give me 1, and clicking on 'Avocado' will give me 2.

Madi
  • 23
  • 1
  • 4
  • 2
    possible duplicate of [JavaScript DOM: Find Element Index In Container](http://stackoverflow.com/questions/11761881/javascript-dom-find-element-index-in-container) – dsgriffin Mar 19 '14 at 06:33

2 Answers2

1

without any framework, try this:

<html>
<head>
<script>
function init(){
l =document.getElementById('myList');
items = l.getElementsByTagName('li');
for(i=0;i<items.length;i++){
    items[i].i = i;
    items[i].onclick = myAlert; 
}
}

function  myAlert() {
alert(this.i)
}
</script>
</head>
<body onload='init()'>
<ul id='myList'>
 <li><span>*</span>Cat</li>
 <li><span>*</span>Dog</li>
 <li><span>*</span>Avocado</li>
</ul>
</body>
</html>

JsFiddle

Christophe Debove
  • 6,088
  • 20
  • 73
  • 124
ominiverdi
  • 11
  • 1
  • If there are nested UL or OL elements this may fail (the OP doesn't make it clear how to handle nested lists). – RobG Mar 19 '14 at 07:02
  • Madison, thanks, if you like the answer please accept it. if you prefer the nested script from Rob please accept his. enjoy! – ominiverdi Mar 19 '14 at 13:25
1

The usual trick is to find the LI that the click came from, the get its parent UL and loop over the LI children to find the subject LI:

<ul id="ul0">
  <li><span>first</span>
  <li><span>second</span>
  <li><span>third</span>
</ul>

<script>

document.getElementById('ul0').addEventListener('click', showIndex, false);

function showIndex(event) {
  var index;
  var element = event.target;

  if (element.tagName.toLowerCase() != 'li') {
    element = upTo('li', element);
  }

  if (element) {
     index = getIndex(element);
  }
  console.log(index);
  return index;
}

// Get the index of an LI in a UL
// Index is zero based
function getIndex(li) {
  var ul = li.parentNode;
  var node;
  var nodes = ul.childNodes;

  // Traverse child nodes, counting LIs until element found
  for (var i=0, j=0, iLen=nodes.length; i<iLen; i++) {
    node = nodes[i]

    if (node.tagName && node.tagName.toLowerCase() == 'li') {

      if (node == li) {
        return j;
      }
      j++;
    }
  }
  return null;  
}

// Start from root and find ancestor with tagName
// Returns undefined if element not found
function upTo(tagName, root) {

  if (!root) return;
  tagName = tagName.toLowerCase();

  while (root.parentNode) {
    root = root.parentNode;

    if (root.tagName && root.tagName.toLowerCase() == tagName) {
       return root;
    }
  }
}
</script>

This could also handle LIs within an OL by seeing if the LI's parent is an OL and if so, just return li.value.

RobG
  • 142,382
  • 31
  • 172
  • 209