异步即时加载的树控件

一个异步即时加载的树控件,JS+Ajax实现.主要原理是页面加载时仅加载一级子树,当点击子树结点时再即时加载其二级结点,往下同理.和TreeView的加载方案完全不同,这对于枝繁叶茂的树的加载效率有明显提高.笔者在加载行政区划信息时,采用单线程递归的同步方式加载要1分多钟,改成非递归后约35秒,后又改成多线程约20秒.而改成异步即时加载的方式后前台基本上感觉不到树的加载.对于更大的树来说效果必然更加可观.代码如下:
  
  var extendSign = "+";
    var shrinkSign = "-";
    var noneSign = "    ";
    var TreeList = null;
    function TreeControl(controlID,controlName,CallBackFunc)
    {
        this.controlID = controlID;
        this.CallBackFunc = CallBackFunc;
        this.controlName = controlName;
        
        if($(controlID) == null)
        {
            this.CreateRoot();
            CallBackFunc(this,"div_" + this.controlID,-1);
            
            if(TreeList == null)
            {
                TreeList = new Array();
                document.detachEvent('onclick', HideTreeList);
                document.attachEvent('onclick', HideTreeList);
            }
            
            TreeList.push(this);
        }
    }
    TreeControl.prototype.Show = function(eventSource,solveFunc)
    {
        this.eventSource = (eventSource == undefined || eventSource == null ? event.srcElement : $(eventSource));
        if(solveFunc != undefined && solveFunc != null)
        {
            this.solveFunction = solveFunc;
        }
        this.setClickBolder();
        
        var leftpos = 0, toppos = 0;
        var ev = this.eventSource;
        while(ev.tagName.toUpperCase() != "HTML" && ev.tagName.toUpperCase() != "BODY")
        {
      leftpos += ev.offsetLeft;
      toppos += ev.offsetTop;
      ev = ev.offsetParent;
        }
        $(this.controlID).style.left = leftpos;
        $(this.controlID).style.top = toppos + 17;    
        $(this.controlID).style.display = 'block';
    }
    TreeControl.prototype.CreateRoot = function()
    {
        var strHTML = "";
        var divObj = document.createElement("div");
            
        divObj.id = this.controlID;    
        divObj.style.left=(document.body.clientWidth-220)/2;
        divObj.style.width="100px";
        divObj.style.top="100px";
        divObj.style.backgroundColor="#fffff2";
        divObj.style.display="none";
        divObj.style.height="auto";
        divObj.style.zIndex="999";
        divObj.style.position="absolute";
        divObj.className='layer';
        strHTML += "<div id='div_" + this.controlID + "' class='scroll' onclick='" + this.controlName + ".setClickBolder();' style='width:150px; height:250px; overflow:auto' title='树控件' >";
        strHTML += "</div>";
        strHTML += "<input id='ipt_" + this.controlID + "_SelectData' type='hidden' />";
            
        divObj.innerHTML = strHTML;
        document.body.appendChild(divObj);
    }
    TreeControl.prototype.CreateLeaf = function(parentID,dataStr)
    {
        var totalHtmlStr = "";
        var dataList = (Trim(dataStr) != '' ? dataStr.split('/xFE') : new Array());  
        
        totalHtmlStr += " <table id='tbl_" + leafName + "' style='width: auto' border='0' cellspacing='0' cellpadding='0'>";
        
        for(var i=0;i<dataList.length;i++)
        {
            var curHtmlStr = "";
            var leafName = parentID.substring(4)+"_" + i;
            var inDataList = dataList.split('/xFD');
            
            curHtmlStr += "     <tr>";
            curHtmlStr += "         <td nowrap style='width: 0%' align='center'>";
            curHtmlStr += "             <a id='a_" + leafName + "' style='cursor: hand' src='javascript:' onclick='" + this.controlName
                + ".VerifyNode(" + "/"div_" + leafName + "/"," + inDataList[0] + ")' title = '展开[" + inDataList[1] + "]'>" + extendSign + "</a>&nbsp;";
            curHtmlStr += "         </td>";
            curHtmlStr += "         <td nowrap style='width: 100%' align='left'>";
            curHtmlStr += "             <label id='lbl_" + leafName + "' style='cursor: hand' onclick='" + this.controlName + ".GetData();' title='选择["
                + inDataList[1] + "]' >" + inDataList[1] + "</label>";
            curHtmlStr += "         </td>";
            curHtmlStr += "     </tr>";
            curHtmlStr += "     <tr>";
            curHtmlStr += "         <td nowrap style='width: 0%' align='center'>";
            curHtmlStr += "         </td>";
            curHtmlStr += "         <td nowrap style='width: 100%' align='left'>";
            curHtmlStr += "             <div id='div_" + leafName + "' style='width: 100%;display:none' border='0' cellspacing='0' cellpadding='0'>";
            curHtmlStr += "             </div>"
            curHtmlStr += "         </td>";
            curHtmlStr += "     </tr>";
            
            totalHtmlStr += curHtmlStr;
        }
        
        totalHtmlStr += " </table>";
        
        $(parentID).innerHTML = totalHtmlStr;
        
        if($('a_' + parentID.substring(4)) != null)
        {
            if(Trim(dataStr) == '')
            {
                $('a_' + parentID.substring(4)).innerHTML = noneSign;
                $('a_' + parentID.substring(4)).style.cursor = '';
                $('a_' + parentID.substring(4)).title = "结点[" + $("lbl_"+parentID.substring(4)).innerText + "]已是最底层!";
            }
            else
            {
                $('a_' + parentID.substring(4)).innerHTML = shrinkSign;
                $('a_' + parentID.substring(4)).title = "折叠[" + $("lbl_"+parentID.substring(4)).innerText + "]";
                $(parentID).style.display = 'block';
            }
        }
    }
    TreeControl.prototype.GetData = function()
    {
        var lblObj = event.srcElement;
        
        while(lblObj.tagName != "LABEL")
        {
            lblObj = lblObj.parentNode;
        }
            
        var strData=Trim(lblObj.innerText);
        
        if(typeof(this.solveFunction)=="undefined" || this.solveFunction==null)
        {
            this.eventSource.value = strData;
        }
        else
        {    
            this.solveFunction(strData);
        }
        
        this.hideBodyMenu();
    }
    TreeControl.prototype.VerifyNode = function(parentID,currid)
    {
        var aObj = event.srcElement;
        
        while(aObj.tagName != 'A' && aObj.tagName != 'BODY')
        {
            aObj = aObj.parentNode;
        }
        
        if(aObj.tagName != 'A' || aObj.innerHTML == noneSign)
        {
            return;
        }
        
        if(aObj.innerHTML == extendSign)
        {    
            if(Trim($(parentID).innerHTML) == '')
            {
                this.CallBackFunc(this,parentID,currid);
            }
            else
            {
                $(parentID).style.display = 'block';
                aObj.innerHTML = shrinkSign;
                aObj.title = "折叠[" + $("lbl_"+parentID.substring(4)).innerText + "]";
            }
        }
        else
        {
            $(parentID).style.display = 'none';
            aObj.innerHTML = extendSign;
            aObj.title = "展开[" + $("lbl_"+parentID.substring(4)).innerText + "]";
        }
    }
    TreeControl.prototype.setClickBolder = function()
    {
        this.clickBolder = true;
    }
    TreeControl.prototype.hideBodyMenu = function()
    {
        if(this.clickBolder)
        {
            this.clickBolder = false;
        }
        else
        {
            $(this.controlID).style.display = 'none';
        }
    }
    function HideTreeList()
    {
        for(var i=0 ; i<TreeList.length ; i++)
        {
            TreeList.hideBodyMenu();
        }
    }

    示例:
    //前台:
    
    var tree = new TreeControl("tree","tree",TreeGetData);
    function TreeGetData(control,parentID,currid)
    {
        Test.GetAreaInfo(currid,SolvFunc);
        function SolvFunc(response)
        {
            control.CreateLeaf(parentID,response.value);
        }
    }

    //后台
    [Ajax.AjaxMethod]
    public string GetAreaInfo(int parentId)
    {
        string condition = "codesetid = 'AB' and parentid = ";
        condition += (parentId == -1 ? "codeitemid" : Convert.ToString(parentId) + " and parentid <> codeitemid");
        DataTable dt = DBTableOpt.Select("codeitemid,codeitemdesc", "codeitem", condition, null, null, "codeitemid");
        return PubBaseOpt.getCellString(0, 100, "/xFE", "/xFD", dt, out curPageNum, out totalPageNum, out totalRecord);
    } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值