希望在网页上能够显示树形菜单,鼠标右键点击节点弹出菜单(增加、删除、重命名),点击增加可以在该节点下增加一个子节点,点击删除则将该节点及其子节点全部删除,点击重命名,可以给该节点重命名,请问各位高手该功能应该如何实现,谢谢!

解决方案 »

  1.   

    //========================================
    //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 addedfunction nodeitem_setTag( obj ) {
        this.tag = obj ;
    }function nodeitem_getTag() {
        return this.tag ;
    }
      

  2.   

    [code=JScript]//========================================
    //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 addedfunction nodeitem_setTag( obj ) {
        this.tag = obj ;
    }function nodeitem_getTag() {
        return this.tag ;
    }[/code]
      

  3.   

    function Node(id, pid, name, url, title, target, icon, iconOpen, open) { this.id = id; this.pid = pid; this.name = name; this.url = url; this.title = title; this.target = target; this.icon = icon; this.iconOpen = iconOpen; this._io = open || false; this._is = false; this._ls = false; this._hc = false; this._ai = 0; this._p;};// Tree objectfunction dTree(objName) { this.config = { target : null, folderLinks : true, useSelection : true, useCookies : true, useLines : true, useIcons : true, useStatusText : false, closeSameLevel : false, inOrder : false } this.icon = { root : 'img/base.gif', folder : 'img/folder.gif', folderOpen : 'img/folderopen.gif', node : 'img/page.gif', empty : 'img/empty.gif', line : 'img/line.gif', join : 'img/join.gif', joinBottom : 'img/joinbottom.gif', plus : 'img/plus.gif', plusBottom : 'img/plusbottom.gif', minus : 'img/minus.gif', minusBottom : 'img/minusbottom.gif', nlPlus : 'img/nolines_plus.gif', nlMinus : 'img/nolines_minus.gif' }; this.obj = objName; this.aNodes = []; this.aIndent = []; this.root = new Node(-1); this.selectedNode = null; this.selectedFound = false; this.completed = false;};// Adds a new node to the node arraydTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) { this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);};// Open/close all nodesdTree.prototype.openAll = function() { this.oAll(true);};dTree.prototype.closeAll = function() { this.oAll(false);};// Outputs the tree to the pagedTree.prototype.toString = function() { var str = '<div class="dtree">\n'; if (document.getElementById) { if (this.config.useCookies) this.selectedNode = this.getSelected(); str += this.addNode(this.root); } else str += 'Browser not supported.'; str += '</div>'; if (!this.selectedFound) this.selectedNode = null; this.completed = true; return str;};// Creates the tree structuredTree.prototype.addNode = function(pNode) { var str = ''; var n=0; if (this.config.inOrder) n = pNode._ai; for (n; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == pNode.id) { var cn = this.aNodes[n]; cn._p = pNode; cn._ai = n; this.setCS(cn); if (!cn.target && this.config.target) cn.target = this.config.target; if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id); if (!this.config.folderLinks && cn._hc) cn.url = null; if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) { cn._is = true; this.selectedNode = n; this.selectedFound = true; } str += this.node(cn, n); if (cn._ls) break; } } return str;};// Creates the node icon, url and textdTree.prototype.node = function(node, nodeId) { var str = '<div class="dTreeNode">' + this.indent(node, nodeId); if (this.config.useIcons) { if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node); if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node; if (this.root.id == node.pid) { node.icon = this.icon.root; node.iconOpen = this.icon.root; } str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />'; } if (node.url) { str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"'; if (node.title) str += ' title="' + node.title + '"'; if (node.target) str += ' target="' + node.target + '"'; if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" '; if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc)) str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"'; str += '>'; } else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id) str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">'; str += node.name; if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>'; str += '</div>'; if (node._hc) { str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">'; str += this.addNode(node); str += '</div>'; } this.aIndent.pop(); return str;};
      

  4.   

    function Node(id, pid, name, url, title, target, icon, iconOpen, open) { this.id = id; this.pid = pid; this.name = name; this.url = url; this.title = title; this.target = target; this.icon = icon; this.iconOpen = iconOpen; this._io = open || false; this._is = false; this._ls = false; this._hc = false; this._ai = 0; this._p;};// Tree objectfunction dTree(objName) { this.config = { target : null, folderLinks : true, useSelection : true, useCookies : true, useLines : true, useIcons : true, useStatusText : false, closeSameLevel : false, inOrder : false } this.icon = { root : 'img/base.gif', folder : 'img/folder.gif', folderOpen : 'img/folderopen.gif', node : 'img/page.gif', empty : 'img/empty.gif', line : 'img/line.gif', join : 'img/join.gif', joinBottom : 'img/joinbottom.gif', plus : 'img/plus.gif', plusBottom : 'img/plusbottom.gif', minus : 'img/minus.gif', minusBottom : 'img/minusbottom.gif', nlPlus : 'img/nolines_plus.gif', nlMinus : 'img/nolines_minus.gif' }; this.obj = objName; this.aNodes = []; this.aIndent = []; this.root = new Node(-1); this.selectedNode = null; this.selectedFound = false; this.completed = false;};// Adds a new node to the node arraydTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) { this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);};// Open/close all nodesdTree.prototype.openAll = function() { this.oAll(true);};dTree.prototype.closeAll = function() { this.oAll(false);};// Outputs the tree to the pagedTree.prototype.toString = function() { var str = '<div class="dtree">\n'; if (document.getElementById) { if (this.config.useCookies) this.selectedNode = this.getSelected(); str += this.addNode(this.root); } else str += 'Browser not supported.'; str += '</div>'; if (!this.selectedFound) this.selectedNode = null; this.completed = true; return str;};// Creates the tree structuredTree.prototype.addNode = function(pNode) { var str = ''; var n=0; if (this.config.inOrder) n = pNode._ai; for (n; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == pNode.id) { var cn = this.aNodes[n]; cn._p = pNode; cn._ai = n; this.setCS(cn); if (!cn.target && this.config.target) cn.target = this.config.target; if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id); if (!this.config.folderLinks && cn._hc) cn.url = null; if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) { cn._is = true; this.selectedNode = n; this.selectedFound = true; } str += this.node(cn, n); if (cn._ls) break; } } return str;};// Creates the node icon, url and textdTree.prototype.node = function(node, nodeId) { var str = '<div class="dTreeNode">' + this.indent(node, nodeId); if (this.config.useIcons) { if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node); if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node; if (this.root.id == node.pid) { node.icon = this.icon.root; node.iconOpen = this.icon.root; } str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />'; } if (node.url) { str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"'; if (node.title) str += ' title="' + node.title + '"'; if (node.target) str += ' target="' + node.target + '"'; if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" '; if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc)) str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"'; str += '>'; } else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id) str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">'; str += node.name; if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>'; str += '</div>'; if (node._hc) { str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">'; str += this.addNode(node); str += '</div>'; } this.aIndent.pop(); return str;};
      

  5.   

    建议:
    一、ajax
    二、自己做服务端控件(以同步实现异步,类似于jsf里的控件但有点差异,效果跟.net里的服务端控件一样,可以参照jsf、tapestry与servlet-jsp的api手册)
      

  6.   

    谢谢楼上的鼎力支持!
    我对js实在懂得很少,不知这js代码该如何在jsp页面中调用展现呢?
    还有,我的这些对节点的操作都必须到数据库中更新,这该如何实现呢?
    谢谢回复!