Javascript在单击时获取子项的索引

mel*_*PLS 2 javascript

我已经向父级#carousel-thumbs 添加了一个点击事件。

carouselThumbsContainer.onclick = function(ev) {
    var target = ev.target;    // which child was actually clicked
}

<ul id="carousel-thumbs" class="l-grid">
    <li class="active"><a class="active" href="#"><img src="img/carousel-1-th.jpg" /></a></li>
    <li><a href="#"><img src="img/carousel-2-th.jpg" /></a></li>
    <li><a href="#"><img src="img/carousel-3-th.jpg" /></a></li>
    <li><a href="#"><img src="img/carousel-4-th.jpg" /></a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我想返回点击元素相对于其父元素的索引。所以如果用户点击第二个

  • 我会得到 1。

    ///////////////////////////////////////// 目前的解决方案有效,但我是希望简化:

        //Add a click event to each thumn in the thumbs container
    for (var j = 0, len = carouselThumbsContainer.children.length; j < len; j++){
        (function(index){
            carouselThumbsContainer.children[j].onclick = function(){
                  console.log(index);
            }    
        })(j);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    对 Javascript 一无所知,我认为必须有一种更简单的方法,但也许不是。

  • lea*_*eaf 5

    试试这个(另请阅读:什么是 DOM 事件委托?):

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这是一个演示:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
    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;
    }
    Run Code Online (Sandbox Code Playgroud)
    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; }
    Run Code Online (Sandbox Code Playgroud)


    逐行单击处理程序

    演员们

    var tgt = e.target, i = 0, items; // and `this`
    
    Run Code Online (Sandbox Code Playgroud)

    this是 UL 本身。e.target是发起事件的 DOM 元素。它可以是 UL 的任何后代或 UL 本身(在本例中为e.target= this)。i保存点击项目的索引。items代表 LI 是 UL 的直接子代。

    故事

    如果目标是 UL 本身,则退出函数:

    if (tgt === this) return;
    
    Run Code Online (Sandbox Code Playgroud)

    获取作为 UL 的直接子代的 LI:

    items = children(this);
    
    Run Code Online (Sandbox Code Playgroud)

    冒泡通过目标的祖先直到到达最上面的 LI:

    while (tgt.parentNode !== this) tgt = tgt.parentNode;
    
    Run Code Online (Sandbox Code Playgroud)

    递增索引,直到目标与 LI 之一匹配:

    while (items[i] !== tgt) i++;
    
    Run Code Online (Sandbox Code Playgroud)

    提醒索引:

    alert(i);
    
    Run Code Online (Sandbox Code Playgroud)