js-列表树
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="iscroll.js"></script> <title>无标题文档</title> <script> var TreeMenu = function (container, options){ this.container = typeof container == 'object' ? container : document.getElementById(container); if(!this.container){ alert('not fund ' + container); return; } this.myScroll = new iScroll(this.container); this.container = this.container.children[0]; this.data = new Array(); this.visitPath = new Array(); this.selected = new Array(); this.options = { multiSelect : true, clickCallback : null, renderCallback : null, currentNode : '0', selectedCss : 'checkbox-s', unSelectedCss : 'checkbox', level1Css : 'notlast', level2Css : '', level3Css : '', lastLevelCss : '' }; this.item = { id : '', parentId : '0', selected : false, lastChild : false, html : '', title : '', //专用 name : '', code : '', unit : '', company : '' }; //设置options if(options){ for( p in this.options) { if( !options.hasOwnProperty(p) ) options[p] = this.options[p]; } this.options = options; } }; TreeMenu.prototype = { //载入数据 push : function (item) { var list = Object.prototype.toString.apply(item) === '[object Array]' ? item : [item]; for( var i=0; i< list.length; i++) { var _item = list[i]; for( p in this.item) { if( !_item.hasOwnProperty(p) ) _item[p] = this.item[p]; } this.data.push(_item); } }, //最后一级 renderAllChild : function(){ var ulElem = document.createElement('ul'); ulElem.id = 'tree_list_all'; ulElem.style.display = 'none'; for(var i=0; i<this.data.length; i++){ var item = this.data[i]; if(!item.lastChild) continue; var itemElem = document.createElement('li'); itemElem.className = this.options.lastLevelCss; itemElem.title = item.title; itemElem.innerHTML = '<span></span>'; var inputElem = itemElem.childNodes[0]; inputElem.id = item.id; inputElem.className = item.selected ? this.options.selectedCss : this.options.unSelectedCss; var p1Elem = document.createElement('p'); p1Elem.innerHTML = item.html; itemElem.appendChild(p1Elem); var p2Elem = document.createElement('p'); p2Elem.innerHTML = item.company + ' > ' + item.unit; itemElem.appendChild(p2Elem); itemElem.item = item; ulElem.appendChild(itemElem); } this.options.currentNode = ulElem.id; this.container.appendChild(ulElem); this.showChildDom(ulElem.id); }, _renderNoChild : function(){ var ulElem = document.createElement('ul'); ulElem.id = 'tree_list_no_child'; ulElem.style.display = 'none'; var spanElem = document.createElement('span'); spanElem.innerHTML = 'no child'; ulElem.appendChild(spanElem); this.container.appendChild(ulElem); this.showChildDom(ulElem.id); }, _render : function(parentId){ var parent = parentId ? parentId : 0; var ulElem = document.createElement('ul'); ulElem.id = 'tree_list_' + parent; ulElem.style.display = 'none'; for(var i=0; i<this.data.length; i++){ var item = this.data[i]; if(item.parentId != parentId) continue; var itemElem = document.createElement('li'); if(!item.lastChild){ itemElem.className = this.options.level1Css; itemElem.title = item.title; var pElem = document.createElement('p'); pElem.innerHTML = item.html; itemElem.appendChild(pElem); }else{ itemElem.className = this.options.lastLevelCss; itemElem.title = item.title; itemElem.innerHTML = '<span></span>'; var inputElem = itemElem.childNodes[0]; inputElem.id = item.id; inputElem.className = item.selected ? this.options.selectedCss : this.options.unSelectedCss; var p1Elem = document.createElement('p'); p1Elem.innerHTML = item.html; itemElem.appendChild(p1Elem); var p2Elem = document.createElement('p'); p2Elem.innerHTML = item.company + ' > ' + item.unit; itemElem.appendChild(p2Elem); } itemElem.item = item; ulElem.appendChild(itemElem); } this.options.currentNode = ulElem.id; this.container.appendChild(ulElem); this.showChildDom(ulElem.id); }, render : function (parentid){ var parent = parentid ? parentid : 0; var child = this.haveChild(parent); if(child){ this._render(parent); }else{ // this._renderNoChild(); } var call = this.options.renderCallback; if(call){ call(this); } this.myScroll._checkDOMChanges(); this.container.onclick = this.onClick; this.container._this = this; }, onClick :function (e) { e = e || window.event; var target = e.target || e.srcElement; var _this = this._this; var item = target.item || target.parentNode.item || target.parentNode.parentNode.item; if(!item){ return; } if(item.lastChild){ item.checked = !item.checked; target.childNodes[0].className = item.checked ? _this.options.selectedCss : _this.options.unSelectedCss if(_this.options.clickCallback){ _this.options.clickCallback(item); }; return; } //保存路径 _this.visitPath.push(item); if(!_this.findChildDOM(item.id)){ _this.render(item.id); }else{ _this.showChildDom(item.id); } }, haveChild : function (id) { for( var i=0;i < this.data.length; i++){ var item = this.data[i]; if( item.parentId == id){ return true; } } return false; }, findChildDOM : function (id) { var childNodes = this.container.childNodes; for(var i=0; i<childNodes.length; i++){ if(id == childNodes[i].id){ return i; } } return null; }, showChildDom : function(id){ var childNodes = this.container.childNodes; if(childNodes.length < 1) {alert('container have no children'); return; } var index = this.findChildDOM(id); if(index == null) {alert('can not find DOM ' + id); return;} var temp = childNodes[index]; this.container.replaceChild(this.container.firstChild,childNodes[index]); this.container.replaceChild(temp,this.container.firstChild); /* childNodes[index] = childNodes[0]; childNodes[0] = temp;*/ childNodes[0].style.display = 'block'; for(var i=1; i<childNodes.length; i++){ childNodes.setAttribute('display','none'); } this.myScroll._checkDOMChanges(); }, remove : function (item, list){ list = list || this.list; for( var i=0;i < list.length; i++) { if( list[i].id == item.id) { list[i].itemElem.parentNode.removeChild(list[i].itemElem); list.splice(i,1); if( item.parent ) { for ( var j=0; j<item.parent.children.length; j++) { if( item.parent.children[j].id == item.id) { item.parent.children.splice(j,1); break; } } item.parent.expand = false; this.renderChild(item.parent); } return list; } } return list; }, refresh : function(){ this.showChildDom(this.options.currentNode) }, reset : function(){ } } </script> </head> <body> <div id="scroll"> <div id="list"> </div> </div> <input type="button" onclick="back();" value="back" /> <input type="button" onclick="expendall();" value="expend all" /> <input type="button" onclick="home();" value="home" /> <input type="button" onclick="refresh();" value="refresh" /> <script> function test(item){ alert(item.html); } function expendall(){ list.renderAllChild(); } function refresh(){ list.refresh(); } function home(){ list.render(); } function back(){ if (list.visitPath.length != 0) { var parentid = list.visitPath.pop().parentId; list.render(parentid); } } var list = new TreeMenu('scroll'); list.push({html : 'aaaa', title : 'aaaa', id : 1}); list.push({html : 'bbb', title : 'bbb', id : 2}); list.push({html : 'ccc', title : 'ccc', parentId: 1, id : 3}); list.push({html : 'ddd', title : 'ddd', parentId: 3, lastChild : true, id : 4, unit : 'mas', company : 'hand'}); list.push({html : 'eee', title : 'eee', parentId: 3, lastChild : true, id : 5, unit : 'joc', company : 'hand'}); list.push({html : 'fff', title : 'fff', parentId: 3, lastChild : true, id : 6, unit : 'sap', company : 'hand'}); list.render(); </script> </body> </html>