纯js中的可折叠列表优化

Collapsable list optimisation in pure js

我正在构建一个可折叠列表,在我尝试优化我的代码时,我发现自己做了一些错误,但出于某种原因仍然有效。

旧代码:http://jsfiddle.net/3pmcrqmj/

function addEvent(element, myEvent, fnc) {
return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false));
}

var list = document.getElementById('list');
var items = list.getElementsByTagName('ul');
var items2 = list.getElementsByTagName('li');

for(var i = 0; len = items.length, i < len ; i++){

    items[i].parentNode.setAttribute('class','collapse');

    addEvent(items[i].parentNode, 'click', function(event) {

        event = event || window.event;

        event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true);

        if(this.getAttribute('class')==='collapse'){
            this.setAttribute('class','expand');
        } else {
            this.removeAttribute('class');
            var temp = this;
            setTimeout(function(){
                temp.setAttribute('class','collapse');
            },200);
        }

    });
}

我的修复尝试:http://jsfiddle.net/3pmcrqmj/1/

function addEvent(element, myEvent, fnc) {
return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false));
}

var list = document.getElementById('list');
var items = list.getElementsByTagName('ul');
var items2 = list.getElementsByTagName('li');

for(var i = 0; len = items.length, i < len ; i++){
    items[i].parentNode.setAttribute('class','collapse');
}

addEvent(list, 'click', function(event) {
    for(var i = 0; len = items.length, i < len ; i++){
        event = event || window.event;

        event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true);

        if(event.target.getAttribute('class')==='collapse'){
            event.target.setAttribute('class','expand');
            target.setAttribute('class','expand');
        } else {
            event.target.setAttribute('class','collapse');
            target.setAttribute('class','collapse');
        }
    }
});

如何正确冒泡,这样我就不必在每个列表项上都插入事件侦听器?

通过检查点击元素的 nodeName ( == li) 和子 <li> 元素的存在来重写处理程序,因此它只作用于那些元素:

addEvent(list, 'click', function (e) {
     e = e || window.event;
     var from = e.target || e.srcElement;
     if (!/^li$/i.test(from.nodeName) ||
         !from.querySelectorAll('li').length) {return true;}
     var expand = /collapse/i.test(from.className || '');
     from.setAttribute('class', expand ? 'expand' : 'collapse');
});

这是您重写的 jsFiddle