/*
By Hangring
#2008.01.21#
---
use list:
> css.lib.js
> events.lib.js
> node.lib.js
> cookie.lib.js
---
树状列表
---
包含样式:
*/
$Defined('Tree');
var Tree = {};
// Argument
// opts : {cookie:true|false,linkExtend:true|false}
Tree.Settle = function (el /* :HTMLElement(object) | :String(HTMLElement id) */, opts /* :Object */) {
if (!oNode.IsNode(el)) el = $(el);
var id = el.id;
this[id] = {el:el,cookies: '',opts:opts || {}};
//this.SetExtendableAll(el);
this.Circle(el, id, '', true);
if (this[id].opts.cookie) {
//Cookie.Del(id);
this.Retrieve(id);
this.Reset(id);
}
};
// setting all
Tree.SetExtendableAll = function (el /* :HTMLElement */) {
var uls = el.getElementsByTagName('ul');
for (var i = 0, len = uls.length; i < len; i++) {
this.SetExtendableOne(uls[i]);
}
};
// setting one
Tree.SetExtendableOne = function (el /* :HTMLElement */) {
var lis = el.childNodes;
var ops = [];
for (var i = 0, j = 0, len = lis.length; i < len; i++) {
if (!oNode.IsNode(lis[i]) || lis[i].tagName.toLowerCase() != 'li')
continue;
ops[j] = {
x: Global.GetOffsetLeft(lis[i]),
y: Global.GetOffsetTop(lis[i]),
index: i
};
j++;
}
var l = Global.GetOffsetLeft(el);
var t = Global.GetOffsetTop(el);
var w = el.offsetWidth + 50;
var h = el.offsetHeight;
el.style.position = 'relative';
el.style.overflow = 'hidden';
el.style.width = w + 'px';
el.style.height = h + 'px';
for (i = 0; i < j; i++) {
var li = lis[ops[i].index];
li.style.position = 'absolute';
li.style.border = '1px solid #f00';
li.style.bottom = h - (ops[i].y - t) - li.offsetHeight + 'px';
}
};
// 循环
Tree.Circle = function (el /* :HTMLElement */, id /* :String */, index /* :String */, first /* :Boolean */) {
var childs = el.childNodes;
for (var i = 0, j = 0, len = childs.length; i < len; i++) {
var child = childs[i];
first || CSS.AddClass(child, 'second');
if (oNode.IsNode(child)) {
var _child = child.getElementsByTagName('ul');
_child = _child && _child.length > 0 ? _child[0] : null;
var icon = oNode.CreateNode('span');
oNode.InsertBefore(icon, child.firstChild);
// index
var _index = icon._index = (index != '' ? index + '_' : '') + j++;
CSS.AddClass(icon, 'icon');
CSS.AddClass(icon, _child ? 'close' : 'item');
if (_child) {
this.Circle(_child, id, _index);
CSS.SetDisplay(_child, false);
icon.status = 'close';
icon.list = _child;
Events.AttachEvent(icon, 'click', function (e, th) {
th = th || this;
extend(th, true);
});
if (Tree[id].opts.linkExtend) {
var a = child.getElementsByTagName('a');
if (a.length > 0 && a[0].parentNode == child) {
a = a[0];
a.icon = icon;
Events.AttachEvent(a, 'click', function (e, th) {
th = th || this;
extend(th.icon, false);
Events.CancelEvent(e);
});
}
}
}
}
}
function extend (th, icon) {
if (th.status == 'close') {
th.status = 'open';
CSS.ReplaceClass(th, 'close', 'open');
CSS.SetDisplay(th.list, true);
if (Tree[id].opts.cookie) {
// add current level
var cookie_index = Tree[id].cookies;
Tree.ReplaceIndex(cookie_index, th._index);
if (cookie_index != '') {
cookie_index += ',';
}
Tree[id].cookies = cookie_index + th._index;
// set cookie
Cookie.Set(id, Tree[id].cookies);
}
}
else {
th.status = 'close';
CSS.ReplaceClass(th, 'open', 'close');
CSS.SetDisplay(th.list, false);
if (Tree[id].opts.cookie) {
// delete current level
var cookie_index = Tree[id].cookies;
cookie_index = Tree.ReplaceIndex(cookie_index, th._index);
Tree[id].cookies = cookie_index;
// set cookie
Cookie.Set(id, Tree[id].cookies);
}
}
}
};
// 清理需要保存的索引
Tree.ReplaceIndex = function (indexs /* :String(index1,index2,index3) */, index /* :String */) {
indexs = indexs.replace(',' + index + ',', ',');
indexs = indexs.replace(new RegExp(',' + index + '$'), '');
indexs = indexs.replace(new RegExp('^' + index + ','), '');
indexs = indexs.replace(new RegExp('^' + index + '$'), '');
return indexs;
};
// 重新获取cookie的内容
Tree.Retrieve = function (id /* :String(HTMLElement id) */) {
var cookies = Cookie.cookies[id];
if (!cookies || cookies == 'undefined' || typeof cookies == 'undefined') cookies = '';
this[id].cookies = cookies;
//alert('=' + cookies + '=');
};
// 重设已记录的展开的列表
Tree.Reset = function (id /* :String(HTMLElement id) */) {
var cookies = this[id].cookies.split(',');
for (var i = 0, len = cookies.length; i < len; i++) {
var levels = cookies[i].split('_');
Tree.OpenTo(id, levels);
}
};
// 展开某个列表
Tree.OpenTo = function (id /* :String(HTMLElement id) */, levels /* :Array([level1, level2, level3, ...]) */) {
var node = null;
for (var i = 0, len = levels.length; i < len; i++) {
if (i == 0) node = this[id].el;
for (var j = 0, k = 0, _len = node.childNodes.length; j < _len; j++) {
if (node.childNodes[j].tagName && node.childNodes[j].tagName.toLowerCase() == 'li') {
if (k == levels[i]) {
node = node.childNodes[j];
break;
}
k++;
}
}
var span = node.getElementsByTagName('span')[0];
span.status = 'open';
CSS.ReplaceClass(span, 'close', 'open');
node && (node = node.getElementsByTagName('ul')[0]);
node && CSS.SetDisplay(node, true);
}
};
/*
样式设计:
ul.tree, ul.tree ul {
padding: 0;
margin: 0;
}
ul.tree li {
clear: both;
padding: 0;
margin: 0;
line-height: 20px;
list-style-type: none;
}
ul.tree li.second {
margin: 0 0 0 20px;
}
ul.tree span.icon {
float: left;
width: 12px;
height: 9px;
margin: 4px 2px 0;
cursor: pointer;
}
ul.tree span.open {
background: transparent url(images/icons.gif) no-repeat 2px -204px;
}
ul.tree span.close {
background: transparent url(images/icons.gif) no-repeat 2px -104px;
}
ul.tree span.item {
height: 14px;
margin-top: 2px;
cursor: default;
background: transparent url(images/icons.gif) no-repeat 0 -301px;
}
脚本:
Tree.Settle(HTMLElement, {cookie:true|false});
*/