鸟食轩的"SmartNavigation"补充版

简介:

关于asp.net的页面回滚后状态的保存一直是我头痛的问题.

我之前的处理方法是写一个函数来处理页面的定位问题.

这个函数也是参考了很多人的处理方法,自己再稍微处理了一下,代码如下:

#region Retain Events
        protected void Retain()
        {
            StringBuilder saveScrollPosition = new StringBuilder ();
            StringBuilder setScrollPosition = new StringBuilder ();

            RegisterHiddenField("__SCROLLPOS", "0");


            saveScrollPosition.Append("<script language='javascript'>");
            saveScrollPosition.Append("document.body.id='MyBody';");
            saveScrollPosition.Append("function saveScrollPosition() {");
            saveScrollPosition.Append("    document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
            saveScrollPosition.Append("}");        
            saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");
            
            saveScrollPosition.Append("</script>");

            RegisterStartupScript("saveScroll", saveScrollPosition.ToString());


            if (Page.IsPostBack)
            {
                setScrollPosition.Append("<script language='javascript'>");
                setScrollPosition.Append("function setScrollPosition() {");
                setScrollPosition.Append("    MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
                setScrollPosition.Append("}");
                setScrollPosition.Append("MyBody.onload=setScrollPosition;");
                setScrollPosition.Append("</script>");

                RegisterStartupScript("setScroll", setScrollPosition.ToString());
            
            }

        }


        protected void Retain(string div)
        {
            string[] divs = {div};
            Retain(divs);
        }

        protected void Retain(string[] divs)
        {
            StringBuilder saveScrollPosition = new StringBuilder ();
            StringBuilder setScrollPosition = new StringBuilder ();

            RegisterHiddenField("__SCROLLPOS", "0");
            

            saveScrollPosition.Append("<script language='javascript'>");
            saveScrollPosition.Append("document.body.id='MyBody';");
            saveScrollPosition.Append("function saveScrollPosition() {");
            saveScrollPosition.Append("    document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
            saveScrollPosition.Append("}");
            saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");

            saveScrollPosition.Append("function saveDivDisplay() {");
            
            foreach(string div in divs)
            {
                if ((div != null)||(div != ""))
                {
                    RegisterHiddenField("__"+div,"");
                    saveScrollPosition.Append("    document.forms[0].__"+div+".value = "+div+".style.display;");
                }

            }

            
            saveScrollPosition.Append("}");
            saveScrollPosition.Append("MyBody.onmousedown=saveDivDisplay;");
            
            saveScrollPosition.Append("</script>");

            RegisterStartupScript("saveScroll", saveScrollPosition.ToString());


            if (Page.IsPostBack)
            {
                setScrollPosition.Append("<script language='javascript'>");
                setScrollPosition.Append("function setScrollPosition() {");

                foreach(string div in divs)
                {
                    if ((div != null)||(div != ""))
                    {
                        setScrollPosition.Append("    "+div+".style.display = '" + Request["__"+div] + "';");
                    }

                }


                setScrollPosition.Append("    MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
                setScrollPosition.Append("}");
                setScrollPosition.Append("MyBody.onload=setScrollPosition;");
                setScrollPosition.Append("</script>");

                RegisterStartupScript("setScroll", setScrollPosition.ToString());
                
            }

        }



        #endregion

用隐藏控件来保存值,但是有个问题,再回滚回来之后,页面再处理层的显示的时候会出现跳动.

看了 鸟食轩SmartNavigation系列文章,觉得非常的好用,解决了自己一直苦恼的问题,我想如果在控件里面自动循环出所有的层,然后控件呈现的时候把这些状态还原回去.
但是改了之后发现无法正常工作,估计还是自己太菜了.修改后的代码如下:

    [DefaultProperty("Text")] 
    [ToolboxData("<{0}:ClientNavigation runat=server></{0}:ClientNavigation>")] 
     public  class ClientNavigation : WebControl, INamingContainer, IPostBackDataHandler 
    
        public ClientNavigation() : base() {} 

        #region Properties 
        public int PositionTop 
        
            get 
            
                object obj = ViewState["PositionTop"]; 
                return obj == null ? 0 : (int)obj; 
            }
 
            set 
            
                ViewState["PositionTop"] = value; 
            }
 
        }
 
 
        public int PositionLeft 
        
            get 
            
                object obj = ViewState["PositionLeft"]; 
                return obj == null ? 0 : (int)obj; 
            }
 
            set 
            
                ViewState["PositionLeft"] = value; 
            }
 
        }
 

        public string DivDisplay
        {
            get 
            
                object obj = ViewState["DivDisplay"]; 
                return obj == null ? "''": (string)obj; 
            }
 
            set 
            
                ViewState["DivDisplay"] = value; 
            }
 
        }


        #endregion
 
 
        protected override void Render(HtmlTextWriter writer) 
        
            this.RegisterClientScript(); 
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden"); 
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID); 
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID); 
            writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}:{2}", this.PositionTop,this.PositionLeft,this.DivDisplay)); 
            //writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}", this.PositionTop,this.PositionLeft)); 
            writer.RenderBeginTag(HtmlTextWriterTag.Input); 
            writer.RenderEndTag(); 
        }
 
 


        #region Client Script 
        private void RegisterClientScript() 
        
            const string REGISTER_KEY = "__ClientNavigate586787__"; 
            string strScript = @" 
            <script language=""javascript""> 
            window.attachEvent('onload', CLN_ClientNavigation); 
            function CLN_ClientNavigation() 
            {{ 
                var scrollTop = {0}; 
                var scrollLeft = {1}; 
                var scrollCount = 0; 
                var divdisplay = {2};    

                var dis = divdisplay.split('$$$');                                    
                
                do 
                {{ 
                    scrollCount ++; 
                    window.scrollTo(scrollLeft, scrollTop); 
                }} 
                while(document.body.scrollTop < scrollTop && scrollCount < 10 ); 
                
                var divs = document.getElementsByTagName('div');
                for(i=0;i<divs.length;i++)
                {{
                    if (dis[i+1] != null)
                    divs[i].style.cssText = dis[i+1];
                }}
            }} 
            document.body.onscroll = function() 
            {{ 
                var body = document.body; 
                
                var dis = ' ';
                var divs = document.getElementsByTagName('div');
                
                for(i=0;i<divs.length;i++) 
                {{
                    
                    dis = dis + '$$$' + divs[i].style.cssText;
                }}
                document.all.{3}.value = body.scrollTop + ':' + body.scrollLeft+ ':' + dis; 
                
            }} 
    
    


            </script>"; 


            if ( !this.Page.IsStartupScriptRegistered(REGISTER_KEY) ) 
            
                strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.DivDisplay, this.ClientID); 
                //strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.ClientID); 
                this.Page.RegisterStartupScript(REGISTER_KEY, strScript); 
            }
 
        }
 
        #endregion
 
 
        #region IPostBackDataHandler interface 

        public void RaisePostDataChangedEvent() 
        
            // TODO:  Add ClientNavigation.RaisePostDataChangedEvent implementation 
        }
 


        public bool LoadPostData(string postDataKey, NameValueCollection postCollection) 
        
            bool modify = false
            string postData = postCollection[postDataKey]; 
            if ( !StringHelper.IsEmpty(postData) ) 
            
                string [] topleft = postData.Split(new char [] {':'}); 
                int iPositionTop = int.Parse(topleft[0]); 
                int iPostionLeft = int.Parse(topleft[1]); 
                string sDiv = topleft[2];
                if ( iPositionTop != this.PositionTop ) 
                
                    this.PositionTop = iPositionTop; 
                    modify |= true
                }
 
                if ( iPostionLeft != this.PositionLeft ) 
                
                    this.PositionLeft = iPostionLeft; 
                    modify |= true
                }
 
                if ( sDiv != this.DivDisplay)
                {
                    this.DivDisplay = sDiv;
                    modify |= true;
                }

            }
 
            return modify; 
        }
 

        #endregion
 
    }
 


不知道是否有更好的解决方法.

本文转自浪子博客园博客,原文链接:http://www.cnblogs.com/walkingboy/archive/2005/07/29/202746.html,如需转载请自行联系原作者
目录
相关文章
|
2天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
4天前
|
云安全 数据采集 人工智能
古茗联名引爆全网,阿里云三层防护助力对抗黑产
阿里云三层校验+风险识别,为古茗每一杯奶茶保驾护航!
古茗联名引爆全网,阿里云三层防护助力对抗黑产
|
4天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
534 2
kde
|
4天前
|
人工智能 关系型数据库 PostgreSQL
n8n Docker 部署手册
n8n是一款开源工作流自动化平台,支持低代码与可编程模式,集成400+服务节点,原生支持AI与API连接,可自托管部署,助力团队构建安全高效的自动化流程。
kde
362 3
|
2天前
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
751 4
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
|
3天前
|
JavaScript 开发工具 Android开发
如何在原生 App 中调用 Uniapp 的页面?
如何在原生 App 中调用 Uniapp 的页面?
243 138
|
4天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践
本文介绍RAG(检索增强生成)技术,结合Spring AI与本地及云知识库实现学术分析AI应用,利用阿里云Qwen-Plus模型提升回答准确性与可信度。
254 91
AI 超级智能体全栈项目阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践