1.首先给大家贴出TV20的源码
//
========================================
//
Envrionment to hold Listeners
//
========================================
tv_listeners
=
new
Array() ;
function
listener( type , handler )
...
{ this .type = type ; this .handler = handler ; this .id = tv_listeners.length ; tv_listeners[ tv_listeners.length ] = this ; }
function
addListener( type , handler )
...
{ new listener( type , handler ) ; }
//
=== END =====
//
=========================================
//
Hold the top item
//
=========================================
tv_topnodeitem
=
null
;
//
===== END =======
//
=========================================
//
Hold nodeitems , and supply a nodeitem Register
//
=========================================
nodeitems
=
new
Array() ;
function
nodeitemRegister( obj )
...
{ nodeitems[ nodeitems.length ] = obj ; return nodeitems.length - 1 ; }
//
=== END =======
//
=================================
//
Custom a stack
//
Class : stack
//
metheds : get()
//
put( obj )
//
=================================
function
stack()
...
{ this .value = new Array() ; this .cursor = 0 ; }
function
stack_get()
...
{ this .cursor = this .cursor - 1 ; return this .value[ this .cursor ] ; }
function
stack_put( obj )
...
{ this .value[ this .cursor ] = obj ; this .cursor = this .cursor + 1 ; }
stack.prototype.get
=
stack_get ; stack.prototype.put
=
stack_put ;
//
=======END ==========
//
=========================================
//
Define a public stack
//
=========================================
userstack
=
new
stack() ;
//
====== END ===========
//
=========================================
//
Image List
//
=========================================
treeview_box_0_none
=
"
images/4_clos.gif
"
; treeview_box_0_line
=
"
images/4_none.gif
"
; treeview_box_2_open
=
"
images/2_open.gif
"
; treeview_box_2_none
=
"
images/2_none.gif
"
; treeview_box_2_close
=
"
images/2_clos.gif
"
; treeview_box_1_open
=
"
images/3_open.gif
"
; treeview_box_1_none
=
"
images/3_none.gif
"
; treeview_box_1_close
=
"
images/3_clos.gif
"
;
//
===============================================
//
Class : nodeitem
//
status------------------------1:two-direction 0:nobox 0: disactivite
//
2:three-0direction 1:close-box 1: activite
//
2:open-box
//
===============================================
function
nodeitem( parentkey , key , lable , img )
...
{ this .lable = lable ; this .key = key ; this .parent = findNode( parentkey ) ; if ( this .parent != null ) ... { aa = this .parent.status ; if ( aa.substring( 1 , 2 ) == " 0 " ) this .parent.status = aa.substring( 0 , 1 ) + " 1 " + aa.substring( 2 , 3 ) ; if ( this .parent.maxsubitem != null ) this .parent.maxsubitem.status = " 2 " + this .parent.maxsubitem.status.substring( 1 , 3 ) ; this .parent.subitems[ this .parent.subitems.length ] = this ; this .parent.maxsubitem = this ; } else ... { if ( tv_topnodeitem != null ) ... { alert( " 不能有两个顶项! " ) ; return ; } tv_topnodeitem = this ; } this .img = img ; this .tag = null ; this .status = " 100 " ; this .subitems = new Array() ; this .maxsubitem = null ; this .id = nodeitemRegister( this ) ; // ********************** this .questionId = 0 ; this .description = "" ; // this.url = null; // ********************** // added by msb for the sort and move up/down /**/ /* if ( this == tv_topnodeitem ) { this.nodeIndex = 0; } else { this.nodeIndex = this.parent.subitems.length; } */ // end added }
//
added by msb for the sort and move up/down
function
nodeitem_moveUp()
...
{ if ( this == tv_topnodeitem) return ; // topitem ssubitems = this .parent.subitems; for ( i = 0 ; i < ssubitems.length; i ++ ) ... { if ( ssubitems[i] == this ) ... { break ; } } if (i == 0 ) return ; ssubitems[i] = ssubitems[i - 1 ]; ssubitems[i - 1 ] = this ; if (i == ssubitems.length - 1 ) ... { ssubitems[i - 1 ].status = " 2 " + ssubitems[i - 1 ].status.substring( 1 , 3 ); ssubitems[i].status = " 1 " + ssubitems[i].status.substring( 1 , 3 ); } /**/ /* itemTemp = this; ssubitems[this.nodeIndex-1] */ /**/ /* for ( i=0; i<ssubitems.length; i++ ) { if( ssubitems[i] != null && ssubitems[i].nodeIndex == (this.nodeIndex-1) ) previousitem = ssubitems[i] } previousitem.nodeIndex = this.nodeIndex; this.nodeIndex = this.nodeIndex -1; swap(this,previousitem); */ // label_on_click(this.id); this .parent.refresh(); lable_on_click( this .id); }
//
moveUp()
function
nodeitem_moveDown()
...
{ if ( this == tv_topnodeitem) return ; // topitem ssubitems = this .parent.subitems; for ( i = 0 ; i < ssubitems.length; i ++ ) ... { if ( ssubitems[i] == this ) ... { break ; } } if (i == ssubitems.length - 1 ) return ; ssubitems[i] = ssubitems[i + 1 ]; ssubitems[i + 1 ] = this ; if (i == ssubitems.length - 2 ) ... { ssubitems[i + 1 ].status = " 1 " + ssubitems[i + 1 ].status.substring( 1 , 3 ); ssubitems[i].status = " 2 " + ssubitems[i].status.substring( 1 , 3 ); } this .parent.refresh(); lable_on_click( this .id); }
//
moveDown()
/**/
/* function swap (item1, item2) { nodeitems[item1.id] = item2; nodeitems[item2.id] = item1; idTemp = item1.id; item1.id = item2.id; item2.id = idTemp; } */
//
end added
function
nodeitem_setTag( obj )
...
{ this .tag = obj ; }
function
nodeitem_getTag()
...
{ return this .tag ; }
function
nodeitem_show()
...
{ str = " <span id = 'preface " + this .id + " '><table border='0' cellspacing='0' cellpadding='0'><tr><td> " ; str_f = "" ; for ( j = this .parent ; j != null ; j = j.parent ) ... { if ( j.status.substring( 0 , 1 ) == 1 ) str_f = " <img src = ' " + treeview_box_0_none + " ' align='absmiddle'> " + str_f ; else str_f = " <img src = ' " + treeview_box_0_line + " ' align='absmiddle'> " + str_f ; } str = str + str_f ; str += " <img id = 'box " + this .id + " ' nodeid = ' " + this .id + " ' src = ' " ; switch ( this .status.substring( 0 , 2 ) ) ... { case " 10 " : str += treeview_box_1_none ; break ; case " 11 " : str += treeview_box_1_close ; break ; case " 12 " : str += treeview_box_1_open ; break ; case " 20 " : str += treeview_box_2_none ; break ; case " 21 " : str += treeview_box_2_close ; break ; case " 22 " : str += treeview_box_2_open ; break ; } str += " ' align='absmiddle' οnclick='box_on_click(this)'> " ; if ( this .img == "" ) str += this .img ; else str += " <img src = ' " + this .img + " ' align='absmiddle' width='16' height='16'> " ; str += " </td><td><table border='0' cellspacing='1' cellpadding='1' style='font-size:9pt; color:#333333' id='lablePanel " + this .id + " '><tr><td ondblclick = 'lable_on_dblclick( " + this .id + " )' οnclick='lable_on_click( " + this .id + " )' style='cursor:hand' id='f_lablePanel " + this .id + " ' nowrap> " + this .lable + " </td></tr></table></td></tr></table> " ; str += " </span><span id = 'tv_panel_ " + this .id + " ' style='display: " ; if ( this .status.substring( 1 , 2 ) == ' 2 ' ) str += "" ; else str += " none " ; str += " '></span> " ; if ( this .parent == null ) for ( var i in document.all) ... { if (document.all[i].id == " show " ) ... { document.all[i].insertAdjacentHTML( " AfterBegin " , str ) ; break } } else document.all( " tv_panel_ " + this .parent.id ).insertAdjacentHTML( " BeforeEnd " , str ) ; for ( m = 0 ; m < this .subitems.length ; m ++ ) if ( this .subitems[ m ] != null ) ... { userstack.put( m ) ; this .subitems[ m ].show() ; m = userstack.get() ; } }
function
nodeitem_refresh()
...
{ str = " <table border='0' cellspacing='0' cellpadding='0'><tr><td> " ; str_f = "" ; for ( j = this .parent ; j != null ; j = j.parent ) ... { if ( j.status.substring( 0 , 1 ) == 1 ) str_f = " <img src = ' " + treeview_box_0_none + " ' align='absmiddle'> " + str_f ; else str_f = " <img src = ' " + treeview_box_0_line + " ' align='absmiddle'> " + str_f ; } str = str + str_f ; str += " <img id = 'box " + this .id + " ' nodeid = ' " + this .id + " ' src = ' " ; switch ( this .status.substring( 0 , 2 ) ) ... { case " 10 " : str += treeview_box_1_none ; break ; case " 11 " : str += treeview_box_1_close ; break ; case " 12 " : str += treeview_box_1_open ; break ; case " 20 " : str += treeview_box_2_none ; break ; case " 21 " : str += treeview_box_2_close ; break ; case " 22 " : str += treeview_box_2_open ; break ; } str += " ' align='absmiddle' οnclick='box_on_click(this)'> " ; if ( this .img == "" ) str += this .img ; else str += " <img src = ' " + this .img + " ' align='absmiddle' width='16' height='16'> " ; str += " </td><td><table border='0' cellspacing='1' cellpadding='1' style='font-size:9pt; color:#333333' id='lablePanel " + this .id + " '><tr><td ondblclick = 'lable_on_dblclick( " + this .id + " )' οnclick='lable_on_click( " + this .id + " )' style='cursor:hand' id='f_lablePanel " + this .id + " ' nowrap> " + this .lable + " </td></tr></table></td></tr></table> " ; document.all( " preface " + this .id ).innerHTML = str ; document.all( " tv_panel_ " + this .id ).innerHTML = "" ; for ( m = 0 ; m < this .subitems.length ; m ++ ) if ( this .subitems[ m ] != null ) ... { userstack.put( m ) ; this .subitems[ m ].show() ; m = userstack.get() ; } }
function
nodeitem_remove()
...
{ pparent = this .parent ; if ( pparent == null ) ... { removenodeitem( this .id ) ; for ( var i in document.all) ... { if (document.all[i].tagName == " BODY " ) ... { document.all[i].innerHTML = "" ; break } } return ; } lastsubitem = null ; for ( i = 0 ; i < pparent.subitems.length ; i ++ ) if ( pparent.subitems[ i ] != null ) if ( pparent.subitems[ i ] == this ) pparent.subitems[ i ] = null ; else lastsubitem = pparent.subitems[ i ] ; pparent.maxsubitem = lastsubitem ; if ( lastsubitem == null ) pparent.status = pparent.status.substring( 0 , 1 ) + " 0 " + pparent.status.substring( 2 , 3 ) ; else pparent.maxsubitem.status = " 1 " + pparent.maxsubitem.status.substring( 1 , 3 ) ; removenodeitem( this .id ) ; // added by msb for move up/down arrTemp = new Array(); j = 0 ; for ( i = 0 ; i < pparent.subitems.length; i ++ ) ... { if ( pparent.subitems[i] != null ) ... { arrTemp[j] = pparent.subitems[i]; j ++ ; } } this .parent.subitems = arrTemp; // end added pparent.refresh() ; // tv_topnodeitem.refresh() ; }
function
removenodeitem( id )
...
{ curitem = nodeitems[ id ] ; nodeitems[ id ] = null ; for ( m = 0 ; m < curitem.subitems.length ; m ++ ) if ( curitem.subitems[ m ] != null ) ... { userstack.put( m ) ; removenodeitem( curitem.subitems[ m ].id ) ; m = userstack.get() ; } }
function
nodeitem_boxclick()
...
{ if ( this .status.substring( 1 , 2 ) == " 0 " ) return ; if ( this .status.substring( 1 , 2 ) == " 1 " ) this .open() ; else this .close() ; }
function
nodeitem_close()
...
{ this .status = this .status.substring( 0 , 1 ) + " 1 " + this .status.substring( 2 , 3 ) ; document.all( " tv_panel_ " + this .id ).style.display = " none " ; eval( " document.all( 'box' + this.id ).src = treeview_box_ " + this .status.substring( 0 , 1 ) + " _close " ) ; }
function
nodeitem_open()
...
{ this .status = this .status.substring( 0 , 1 ) + " 2 " + this .status.substring( 2 , 3 ) ; document.all( " tv_panel_ " + this .id ).style.display = "" ; eval( " document.all( 'box' + this.id ).src = treeview_box_ " + this .status.substring( 0 , 1 ) + " _open " ) ; }
//
added by msb for the move up/down
nodeitem.prototype.moveUp
=
nodeitem_moveUp; nodeitem.prototype.moveDown
=
nodeitem_moveDown;
//
end added
nodeitem.prototype.show
=
nodeitem_show ; nodeitem.prototype.refresh
=
nodeitem_refresh ; nodeitem.prototype.boxclick
=
nodeitem_boxclick ; nodeitem.prototype.close
=
nodeitem_close ; nodeitem.prototype.open
=
nodeitem_open ; nodeitem.prototype.remove
=
nodeitem_remove ; nodeitem.prototype.setTag
=
nodeitem_setTag ; nodeitem.prototype.getTag
=
nodeitem_getTag ;
//
==========================================================
//
Public Methods
//
==========================================================
function
showTV()
...
{ tv_topnodeitem.show() ; }
function
findNode( key )
...
{ pppp = null ; for ( i = 0 ; i < nodeitems.length ; i ++ ) ... { if ( nodeitems[ i ] != null ) ... { if ( nodeitems[ i ].key == key ) ... { pppp = nodeitems[ i ] ; } } } return pppp ; }
function
addNode( parentkey , key , lable , img )
...
{ return new nodeitem( parentkey , key , lable , img ) ; }
function
deleteNode( key )
...
{ curNode = findNode( key ) ; if ( curNode == null ) return false ; curNode.remove() ; return true ; }
//
====== END ================
//
===========================================================
//
Events
//
===========================================================
function
box_on_click( obj )
...
{ nodeitems[ obj.nodeid ].boxclick() ; }
tv_curlable
=
null
; tv_curlable_f
=
null
;
function
lable_on_click( id )
...
{ key = nodeitems[ id ].key ; if ( nodeitems[ id ].parent == null ) parentkey = "" ; else parentkey = nodeitems[ id ].parent.key ; if ( tv_curlable != null ) ... { tv_curlable.bgColor = " transparent " ; tv_curlable.style.color = " #333333 " ; tv_curlable_f.bgColor = " transparent " ; } tv_curlable = document.all( " lablePanel " + id) ; tv_curlable.bgColor = " #000000 " ; tv_curlable.style.color = " #FFFFFF " ; tv_curlable_f = document.all( " f_lablePanel " + id) ; tv_curlable_f.bgColor = " #888888 " ; for ( i = 0 ; i < tv_listeners.length ; i ++ ) if ( tv_listeners[ i ].type == " click " ) ... { h = tv_listeners[ i ].handler ; eval( h + " ( ' " + key + " ' , ' " + parentkey + " ' ) ; " ) ; } }
function
lable_on_dblclick( id )
...
{ key = nodeitems[ id ].key ; if ( nodeitems[ id ].parent == null ) parentkey = "" ; else parentkey = nodeitems[ id ].parent.key ; if ( tv_curlable != null ) ... { tv_curlable.bgColor = " transparent " ; tv_curlable.style.color = " #333333 " ; tv_curlable_f.bgColor = " transparent " ; } tv_curlable = document.all( " lablePanel " + id) ; tv_curlable.bgColor = " #000000 " ; tv_curlable.style.color = " #FFFFFF " ; tv_curlable_f = document.all( " f_lablePanel " + id) ; tv_curlable_f.bgColor = " #888888 " ; for ( i = 0 ; i < tv_listeners.length ; i ++ ) if ( tv_listeners[ i ].type == " dblclick " ) ... { h = tv_listeners[ i ].handler ; eval( h + " ( ' " + key + " ' , ' " + parentkey + " ' ) ; " ) ; } }
2.我在类别列表页面中使用这段script,使我的类别可以树状显示
<%
...
@ page language = " java " import = " java.util.* " pageEncoding = " GB18030 "
%>
<%
...
@ page import = " java.sql.*,com.ycringfinger.shopping.*,java.util.* "
%>
<%
...
@ include file = " _sessioncheck.jsp "
%>
<%
...
List< Category > categories = Category.getCategories();
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
title
>
用户列表
</
title
>
<
script
language
="javascript"
src
="script/TV20.js"
></
script
>
<
script
type
="text/javascript"
>
...
function t(key, parentkey) ... { document.forms[ " form " ].pid.value = parentkey; } function modify(key, parantkey) ... { window.parent.frames[ " detail " ].location.href = " categorymodify.jsp?id= " + key; }
</
script
>
</
head
>
<
body
>
<
table
align
="center"
border
="1"
>
<
tr
>
<
td
id
="show"
>
</
td
>
</
tr
>
<
tr
>
<
td
>
<
form
name
="form"
action
="categoryadd.jsp"
method
="post"
>
<
input
type
="hidden"
name
="action"
value
="add"
>
Pid:
<
input
type
="text"
name
="pid"
value
=""
readonly
>
<
br
>
Name:
<
input
type
="text"
name
="name"
>
<
br
>
Descr:
<
input
type
="text"
name
="descr"
>
<
br
>
<
input
type
="submit"
value
="添加子类别"
>
</
form
>
</
td
>
</
tr
>
</
table
>
<
script
language
="javascript"
>
...
<!-- addNode(- 1 , 0 , " 所有类别 " , " images/top.gif " ); <% for (Iterator < Category > it = categories.iterator(); it.hasNext();) ... { Category c = it.next(); %> addNode(<%= c.getPid() %> , <%= c.getId() %> , " <%=c.getName()%> " , " images/top.gif " ); <% } %> showTV(); addListener(" click " , " t " ); addListener( " dblclick " , " modify " ) -->
</
script
>
</
body
>
</
html
>
3.使用效果如下图所示: