Try this (also read: What is DOM Event delegation?):
carouselThumbsContainer.onclick = function (e) {
var tgt = e.target, i = 0, items;
if (tgt === this) return;
items = children(this);
while (tgt.parentNode !== this) tgt = tgt.parentNode;
while (items[i] !== tgt) i++;
alert(i);
};
function children(el) {
var i = 0, children = [], child;
while (child = el.childNodes[i++]) {
if (child.nodeType === 1) children.push(child);
}
return children;
}
Here is a demo:
var hit = false,
ul = document.getElementsByTagName('ul')[0],
addButton = document.getElementsByTagName('a')[0],
toggleButton = document.getElementsByTagName('a')[1],
active = null;
ul.onclick = function (e) {
var i = 0, tgt = e.target, items;
if (tgt === this) return;
items = children(ul);
while (tgt.parentNode !== this) tgt = tgt.parentNode;
while (items[i] !== tgt) i++;
hit = true; // for debug purposes only
if (active) active.className = '';
(active = tgt).className = 'active';
output('index : ' + i);
};
addButton.onclick = function () {
var li = document.createElement('li'),
n = children(ul).length + 1;
li.innerHTML = '<a href="#">item ' + n + '</a>';
li.innerHTML += '<ul><li><a href="#">sub item</a></li></ul>';
ul.appendChild(li);
hit = true;
};
toggleButton.onclick = function () {
ul.className = ul.className ? '' : 'sublists';
hit = true;
};
document.onclick = function (e) {
e.preventDefault();
if (hit) hit = false;
else output('index : none');
};
// populate the UL
var i = 0;
while (i++ < 5) addButton.onclick();
hit = false;
// helpers
function children(el) {
var i = 0, children = [], child;
while (child = el.childNodes[i++]) {
if (child.nodeType === 1) children.push(child);
}
return children;
}
function output(s) {
document.getElementsByTagName('span')[0].innerHTML = s;
}
body { font-family: Arial; }
div { width: 210px; padding-left: .5em; }
p a { float: right; color: blue; margin-left: .5em; }
ul { border: 1px solid black; padding: 1em 1em 1em 2.5em; }
ul ul { display: none; }
ul.sublists ul { display: block; }
li a { display: block; color: inherit; text-decoration: none; }
li a { border-right: 90px solid transparent; }
li a:hover { border-right-color: blue; }
li.active a { border-right-color: black; }
li li a { border-right-width: 18px; }
<div>
<p>
<a href="#" title="add a new item">add</a>
<a href="#" title="toggle sub lists">toggle</a>
<span><i>click any item</i></span>
</p>
<ul></ul>
</div>
The click handler line by line
The actors
var tgt = e.target, i = 0, items; // and `this`
this
is the UL itself. e.target
is the DOM element that initiated the event. It can be any descendant of the UL or the UL itself (in this case e.target
= this
). i
holds the index of the clicked item. items
stands for LIs that are direct children of the UL.
The story
Exit the function if the target is the UL itself:
if (tgt === this) return;
Get LIs that are direct children of the UL:
items = children(this);
Bubble up through target's ancestors until reaching the uppermost LI:
while (tgt.parentNode !== this) tgt = tgt.parentNode;
Increment the index until the target matches one of the LIs:
while (items[i] !== tgt) i++;
Alert the index:
alert(i);
, I would like to return the index of the- clicked.
– melMPLS Dec 28 '13 at 20:03