[orginal] OOP treeView based on web.


  abstraction:

    The TreeView control displays a hierarchy of nodes, like the way files and folders are displayed in the

 left pane of the Windows Explorer feature in Windows operating systems,

 Each node in the tree view might contain other nodes, called child nodes.

You can display parent nodes, or nodes that contain child nodes, as expanded or collapsed.  


  introduction:

 to build the treeView control basing on web meaning css, html and js, is not hard to implement, all one needs to do is to build an active css code, you needn't pay too much attention to the js code  it is really easy if you look to the treeview structure it at all depend on recursive way, each node can at the same time be parent and child.


design:

here we see the recursive algorithm for creating the html code for treeview control :

ContractedBlock.gif ExpandedBlockStart.gif Code
function TreeNode(ULiD,txt)
{
  
    
// add the parent node,,
    this.changeToParent=function(liID)
    {
       
       
var li=document.getElementById(liID);
           li.className
='Collapsed ';
       
var ul=document.createElement('ul');
            ul.id
=liID+'P_';
       
var uls=li.getElementsByTagName('ul');
           
if(uls.length<1)
           {
            li.appendChild(ul);
           }
       
return ul.id;
    }


    
var ul=document.getElementById(ULiD);
    
var li=document.createElement('li');
    
//
        li.innerHTML+=txt;
        li.id
=ULiD+'C_'+NodeCount+'_';
        ul.appendChild(li);
        NodeCount
++;
        
        
// recursive:node::
        this.addNode=function(chtxt)
        {
           
var pa=this.changeToParent(li.id);
           
var child=new TreeNode(pa,chtxt)
           
return child;
        }
}


then continue with the class of the treeView control. to use the code below seems reasonable 

ContractedBlock.gif ExpandedBlockStart.gif Code
function TreeView(pid)
{
    
    
var open=true;
     createTreeViewHtmlCode(pid);
     
var obj=document.getElementById(pid);
     
var treeObj=document.getElementById(pid+'tv');
     
     
this.addNode=function(txt)
     {
        
var treeN=new TreeNode(pid+'tv',txt);
        
return treeN;
     }
     
     
     
// the main function for the treeView..

     
     
     
    

   
}
Then one needs to add JavaScript to the page to toggle the applied styles. For this, I decided to go with an approach that could handle multiple styles being applied to a single element, so my solution is a little more complex than a simple className replacement approach:
ContractedBlock.gif ExpandedBlockStart.gif Code
Array.prototype.indexOf = IndexOf;

//Toggles between two classes for an element
function ToggleClass(element, firstClass, secondClass, event)
{
    event.cancelBubble 
= true;
    
    
var classes = element.className.split(" ");
    
var firstClassIndex = classes.indexOf(firstClass);
    
var secondClassIndex = classes.indexOf(secondClass);
    
    
if (firstClassIndex == -1 && secondClassIndex == -1)
    {
        classes[classes.length] 
= firstClass;
    }
    
else if (firstClassIndex != -1)
    {
        classes[firstClassIndex] 
= secondClass;
    }
    
else
    {
        classes[secondClassIndex] 
= firstClass;
    }
    
    element.className 
= classes.join(" ");
    
}

//Finds the index of an item in an array
function IndexOf(item)
{
    
for (var i=0; i < this.length; i++)
    {        
        
if (this[i] == item)
        {
            
return i;
        }
    }
    
    
return -1;
}
I then wrote a script to setup the treeview based on a nested list container. The main reason according to which I chose not to have all the event wiring in the HTML itself, is that my approach leads to cleaner markup and allows one to easily convert any unordered list into a treeview. Here is the script to hook up the click events (it works in both IE and FireFox):


ContractedBlock.gif ExpandedBlockStart.gif Code
//The toggle event handler for each expandable/collapsable node
//
- Note that this also exists to prevent any IE memory leaks 
//
(due to circular references caused by this)
function ToggleNodeStateHandler(event)
{
    ToggleClass(
this"Collapsed""Expanded", (event == null? window.event : event);
}

//Prevents the onclick event from bubbling up to parent elements
function PreventBubbleHandler(event)
{
    
if (!event) event = window.event;
    event.cancelBubble 
= true;
}

//Adds the relevant onclick handlers for the nodes in the tree view
function SetupTreeView(elementId)
{
    
var tree = document.getElementById(elementId);
    
var treeElements = tree.getElementsByTagName("li");
    
    
for (var i=0; i < treeElements.length; i++)
    {
        
if (treeElements[i].getElementsByTagName("ul").length > 0)
        {
            treeElements[i].onclick 
= ToggleNodeStateHandler; 
        }
        
else
        {
            treeElements[i].onclick 
= PreventBubbleHandler; 
        }
    }
}



to make it all more convenient for users there is no need for create the html code,

just we call the function:



function   createTreeViewHtmlCode(pid)
{
  
var  ul = document.createElement( ' ul ' );
      ul.className
= ' TreeView ' ;
      ul.id
= pid + ' tv ' ;
      document.getElementById(pid).appendChild(ul);
}
 


here one can observe the entire js code:


ContractedBlock.gif ExpandedBlockStart.gif Code


Array.prototype.indexOf 
= IndexOf;

//Toggles between two classes for an element
function ToggleClass(element, firstClass, secondClass, event)
{
    event.cancelBubble 
= true;
    
    
var classes = element.className.split(" ");
    
var firstClassIndex = classes.indexOf(firstClass);
    
var secondClassIndex = classes.indexOf(secondClass);
    
    
if (firstClassIndex == -1 && secondClassIndex == -1)
    {
        classes[classes.length] 
= firstClass;
    }
    
else if (firstClassIndex != -1)
    {
        classes[firstClassIndex] 
= secondClass;
    }
    
else
    {
        classes[secondClassIndex] 
= firstClass;
    }
    
    element.className 
= classes.join(" ");
    
}

//Finds the index of an item in an array
function IndexOf(item)
{
    
for (var i=0; i < this.length; i++)
    {        
        
if (this[i] == item)
        {
            
return i;
        }
    }
    
    
return -1;
}

//The toggle event handler for each expandable/collapsable node
//
- Note that this also exists to prevent any IE memory leaks 
//
(due to circular references caused by this)
function ToggleNodeStateHandler(event)
{
    ToggleClass(
this"Collapsed""Expanded", (event == null? window.event : event);
}

//Prevents the onclick event from bubbling up to parent elements
function PreventBubbleHandler(event)
{
    
if (!event) event = window.event;
    event.cancelBubble 
= true;
}

//Adds the relevant onclick handlers for the nodes in the tree view
function SetupTreeView(elementId)
{
    
var tree = document.getElementById(elementId);
    
var treeElements = tree.getElementsByTagName("li");
    
    
for (var i=0; i < treeElements.length; i++)
    {
        
if (treeElements[i].getElementsByTagName("ul").length > 0)
        {
            treeElements[i].onclick 
= ToggleNodeStateHandler; 
        }
        
else
        {
            treeElements[i].onclick 
= PreventBubbleHandler; 
        }
    }
}







function  createTreeViewHtmlCode(pid)
{
  
var ul=document.createElement('ul');
      ul.className
='TreeView';
      ul.id
=pid+'tv';
      document.getElementById(pid).appendChild(ul);
}

 
var NodeCount=0;
// this function to create the sub tree, 
//
mean create the ul in the li, or nested ul.
//
 this function to create the li in ul:
function TreeNode(ULiD,txt)
{
  
    
// add the parent node,,
    this.changeToParent=function(liID)
    {
       
       
var li=document.getElementById(liID);
           li.className
='Collapsed ';
       
var ul=document.createElement('ul');
            ul.id
=liID+'P_';
       
var uls=li.getElementsByTagName('ul');
           
if(uls.length<1)
           {
            li.appendChild(ul);
           }
       
return ul.id;
    }


    
var ul=document.getElementById(ULiD);
    
var li=document.createElement('li');
    
//
        li.innerHTML+=txt;
        li.id
=ULiD+'C_'+NodeCount+'_';
        ul.appendChild(li);
        NodeCount
++;
        
        
// recursive:node::
        this.addNode=function(chtxt)
        {
           
var pa=this.changeToParent(li.id);
           
var child=new TreeNode(pa,chtxt)
           
return child;
        }
}




function TreeView(pid)
{
    
    
var open=true;
     createTreeViewHtmlCode(pid);
     
var obj=document.getElementById(pid);
     
var treeObj=document.getElementById(pid+'tv');
     
     
this.addNode=function(txt)
     {
        
var treeN=new TreeNode(pid+'tv',txt);
        
return treeN;
     }
     
     
     
// the main function for the treeView..

     
     
     
    

   
}










now we need to see the way of creating the object  of treeView :


ContractedBlock.gif ExpandedBlockStart.gif Code
var root=new TreeView('tree');
 
var rr=root.addNode('根节点');


 
var dd=rr.addNode('根节点2');
     dd.addNode(
'孩子1');
     dd.addNode(
'孩子1');

 
var ddd=rr.addNode('根节点2');
     ddd.addNode(
'孩子1');
     ddd.addNode(
'孩子1');
 
var dddd=rr.addNode('根节点2');
     dddd.addNode(
'孩子1');
     dddd.addNode(
'孩子1');
     
     
 
var chi=rr.addNode('根节点2');
     chi.addNode(
'孩子2');
     chi.addNode(
'海子3');
 
var shi=rr.addNode('根节点2');
     shi.addNode(
'aaaaao');
 
var shu=shi.addNode('根节点4');
     shu.addNode(
'crearo,,');
     shu.addNode(
'ammar');
     shu.addNode(
'yemen');

but the step must be implemented after you call the header file:

< SCRIPT  type ="text/javascript"  language ="javascript"  src ="treeview.js" ></ SCRIPT >

now one can observe the auto-generation code simultaneously created by the js object above:


ContractedBlock.gif ExpandedBlockStart.gif Code
<!-- Level 1 nodes -->
<DIV id="tree">
<UL id="treetv" class="TreeView">
<LI id="treetvC_0_" class="Expanded ">
根节点
<UL id="treetvC_0_P_">
<LI id="treetvC_0_P_C_1_" class="Collapsed ">
根节点2
<UL id="treetvC_0_P_C_1_P_">
<LI id="treetvC_0_P_C_1_P_C_2_">
孩子1
</LI>
<LI id="treetvC_0_P_C_1_P_C_3_">
孩子1
</LI>
</UL>
</LI>
<LI id="treetvC_0_P_C_4_" class="Collapsed ">
根节点2
<UL id="treetvC_0_P_C_4_P_">
<LI id="treetvC_0_P_C_4_P_C_5_">
孩子1
</LI>
<LI id="treetvC_0_P_C_4_P_C_6_">
孩子1
</LI>
</UL>
</LI>
<LI id="treetvC_0_P_C_7_" class="Collapsed ">
根节点2
<UL id="treetvC_0_P_C_7_P_">
<LI id="treetvC_0_P_C_7_P_C_8_">
孩子1
</LI>
<LI id="treetvC_0_P_C_7_P_C_9_">
孩子1
</LI>
</UL>
</LI>
<LI id="treetvC_0_P_C_10_" class="Collapsed ">
根节点2
<UL id="treetvC_0_P_C_10_P_">
<LI id="treetvC_0_P_C_10_P_C_11_">
孩子2
</LI>
<LI id="treetvC_0_P_C_10_P_C_12_">
海子3
</LI>
</UL>
</LI>
<LI id="treetvC_0_P_C_13_" class="Collapsed ">
根节点2
<UL id="treetvC_0_P_C_13_P_">
<LI id="treetvC_0_P_C_13_P_C_14_">
aaaaao
</LI>
<LI id="treetvC_0_P_C_13_P_C_15_" class="Collapsed ">
根节点4
<UL id="treetvC_0_P_C_13_P_C_15_P_">
<LI id="treetvC_0_P_C_13_P_C_15_P_C_16_">
crearo,,
</LI>
<LI id="treetvC_0_P_C_13_P_C_15_P_C_17_">
ammar
</LI>
<LI id="treetvC_0_P_C_13_P_C_15_P_C_18_">
yemen
</LI>
</UL>
</LI>
</UL>
</LI>
</UL>
</LI>
</UL>
</DIV>


here you see the css style :


Now I want the first level node to be collapsed with a plus image next to it by default to indicate that the node can be expanded. In order to achieve this we can get rid of the li symbols by making the list items float left. This makes them stack up, so then one can set the elements to display at a 100% of the containing element. We then need space to place our treeview expandable image, so we put in a left padding of 37px. To simplify the process you can use a CSS child selector to apply this to all list elements within the treeview, like this:



ContractedBlock.gif ExpandedBlockStart.gif Code
.TreeView li
{

    padding
: 9 0 0 37px;
    float
:left;
    width
:100%;
    height
:9px;
    position
: relative;
    list-style
: none;
    background-image
:url('images/d4.png');
    background-repeat
:no-repeat;
    background-position
:left;
    border-left
:1px #979797 dotted;

    z-index
:1000;

}



The addition of the collapsing and expanding images, and the associated effects to the child nodes is achieved with the help of the following styles:



ContractedBlock.gif ExpandedBlockStart.gif Code
.TreeView, .TreeView ul
{
    margin
:0px;
    padding
:0px;
}
 
LI.Expanded 
{
     background
: url('images/m.png') no-repeat left top;
     border-left
:1px  dotted transparent ;

}
 
LI.Expanded ul
{
    display
: block;
    
}
 
LI.Collapsed 
{
  
     background
: url('images/p.png') no-repeat left top;
     border-left
:1px  transparent dotted;
}
 
 
 
LI.Collapsed ul
{
    display
: none;
}









Moory !! Marisha!!!




转载于:https://www.cnblogs.com/ammar/archive/2009/11/20/1607127.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值