欢迎光临
我们一直在努力

利用ASP脚本制作异步装载的树形结构(二)(转)——好东东!!

建站超值云服务器,限时71元/月

三、客户端代码

   下面是程序的启动页面tree.htm:

 < html >
   < script src="renderer.js" language="javascript" >< /script >
   < head >< /head >
   < body id=bodytree name="bodytree" onload="gettree();" >
     < iframe id=getdata style="display:none"  >< /iframe >
   < /body >
 < /html >
   该页面装载时将执行renderer.js中的gettree函数。html代码中的iframe部分实现了客户端和服务器端的通讯机制。javascript函数gettree的代码如下:

 function gettree() {
    if (event.type == 'load') {
       if (typeof(divtree0)!='object')
          getdata.window.location.href = 'gettreedata.asp?level=0';
    } else {
       try {
          objmanip = eval('divtree' + event.srcelement.getattribute('elementid'));
          if (objmanip.style.display == 'none') {
             objmanip.style.display = '';
          } else {
             objmanip.style.display = 'none';
          }
       } catch (e) {
          getdata.window.location.href = 'gettreedata.asp?level=' + event.srcelement.getattribute('elementid');
       }
       event.cancelbubble = true;
    }
 }
   当文档装载时,onload事件被触发,gettree函数得以执行。函数检查容器divtree0是否存在,并为iframe(id为getdata)读取第一层节点(这些节点的父节点id为0)。如前所述,所有的节点都必须处理鼠标单击事件,而且事件句柄都是gettree函数。当某个节点(如div1)接收到一个鼠标事件时,程序将执行gettree函数中的else部分。如果发送该事件的节点已经读取了子节点,则程序检查这些子节点是否已经显示,然后切换子节点的显示状态,从而实现了该层节点的扩展或折叠效果。检查子节点是否显示的if语句封装在一个try块内,因此当子节点不存在时,程序将执行catch部分,调用服务器脚本gettreedata.asp读取子节点内容。最后,程序设置event.cancelbubble = true,目的是禁止上一层容器处理该事件。

   服务器脚本gettreedata.asp返回的html代码类如:

 < html >
    < body onload="parent.populatetree('1|0|节点1|2|0|节点2|3|0|节点3|4|0|节点4|');" >
    < /body >
 < /html >
   可以看到,这里的onload事件又调用了另外一个javascript函数populatetree。populatetree函数代码如下:

 function populatetree(strdata) {
    var arrsplitdata;
    var icnt;
    var objtempdiv;
    var objmaindiv;
 
    if (strdata=='') return;
    arrsplitdata = strdata.split("|");
 
    objmaindiv = document.createelement('div');
    objmaindiv.id = 'divtree' + arrsplitdata[1];
    objmaindiv.style.csstext = 'position:relative;left:10px;cursor:hand;';
    for (icnt=0;icnt< arrsplitdata.length-1;icnt+=3) {
       objtempdiv = document.createelement('< div onclick='gettree()' onselectstart='return false;' >');
       objtempdiv.id = 'div' + arrsplitdata[icnt];
       objtempdiv.innerhtml = arrsplitdata[icnt+2];
       objtempdiv.setattribute('elementid',arrsplitdata[icnt]);
       objtempdiv.setattribute('parentelementid',arrsplitdata[icnt+1]);
       objtempdiv.style.csstext = 'position:relative;cursor:hand;color:red;width:100px;font-size:x-small;';
       objmaindiv.appendchild(objtempdiv);
    }
    if (arrsplitdata[1]=='0')
       document.body.appendchild(objmaindiv);
    else
       eval('div' + arrsplitdata[1]).appendchild(objmaindiv);
 }
   我们已经知道,populatetree函数由onload事件调用,它的参数是一个字符串,比如上例中的“1|0|节点1|2|0|节点2|3|0|节点3|4|0|节点4|”,它是一个“节点标识|父节点标识|节点文本|……”的列表。

   如果某个节点不含子节点,则该参数是一个空字符串,此时populatetree直接返回。如果子节点存在,则可以利用split函数将子节点列表以数组形式保存。再接下来,就可以创建该层节点的容器,比如divtree0,然后遍历数组创建各个节点,如div1,div2……。如果某个节点的父节点id为0,说明该节点没有父节点,程序将把容器divtree0加入文档的body;否则当该节点的父节点id不为0,则创建与其父节点对应的容器“divtree< < 父节点id > >”。在创建节点的同时指定了鼠标单击事件的句柄gettree函数。

   注:可以修改gettreedata.asp,使其返回的子节点列表(即populatetree的参数)形式为“节点id|节点文本|……”,也就是省略父节点id,因为任何一组子节点列表其父节点总是相同的。同时,还必须修改populatetree函数,使其接受两个参数,第一个参数是子节点列表,第二个是父节点id。当节点数量较多时,采用这种方法有利于减少数据传输量,提高效率。

   四、其他说明

   综上所述,整个程序的工作过程可以描述为:

浏览器读入文档,执行gettree函数。
gettree调用gettreedata.asp,读取第一层节点数据,然后回调populatetree函数。
populatetree函数生成divtree0以及节点div1,div2,……。
用户单击任意一个节点。
gettree函数检查 “divtree< < 节点id > >” 是否已经存在,如存在则切换子节点显示状态,否则读取子节点列表。
gettreedata.asp返回子节点列表,回调populatetree函数。
populatetree生成相应的容器“divtree< < 父节点id > >”,并生成节点“div< < 节点id1 > >”,“div< < 节点id2 > >”……。
重复步骤4。
   运行示例程序步骤如下(默认目录d:inetpubwwwroot):

创建一个目录,把所有文件拷贝到该目录。
在web服务器上发布该目录。
修改tree.dsn中的数据库路径。
修改gettreedata.asp中tree.dsn文件路径。
用浏览器打开tree.htm。
   示例程序中的iframe是隐藏的,如果要显示它,则请删除iframe的属性“style="display:none"”,此时还可以查看节点的html源代码。

   

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 利用ASP脚本制作异步装载的树形结构(二)(转)——好东东!!
分享到: 更多 (0)