鸟食轩

 Microsoft .NET[C#] MVP 2003
随笔 - 429, 文章 - 235, 评论 - 5529, 引用 - 356
数据加载中……

"SmartNavigation"超级瘦身减肥苗条版ClientNavigation

    在我的上两片文章中我介绍了Page类的SmartNavigation属性的实现(.NET Framework 1.1/2.0中 SmartNavigation的实现),M$虽然实现的非常的巧妙,但是这样的“偷梁换柱”同时也带来了一些负面的影响。他们主要表现在这几个方面:
    1、页面不能再使用浏览器提供的forward和backward,因为这两个动作作用在window.document对象上,而我们实际提交的页面是这个document里的IFrame,它是不能被f&b的。这个问题挺郁闷的,因为用户不能backward,在提交的时候会丢失很多第一次未能提交成功的表单信息;
    2、给调试程序代来麻烦,我们看不到当前页面真正的HTML源码,因为服务器response的信息也还是IFrame中,我们只能看到doucment中陈旧的信息;
    3、对于原始页面使用了动态生成html对象的情况,SmartNavigation是肯定出问题的。就是页面更新后,由于doucment实际没有更新,IFrame里也没有处理到动态生成的Html对象。
    4、兼容性,目前的SmartNavigation都没有考虑兼容性问题,像Opera, Konqueror等浏览器,不能正确地Navigate;
    5、不能获取Request.UrlReferrer引用,UrlReferrer总是空;
    6、对于提交表单后,使用rander一段alert(...)来产生对用户提示的页面,在使用SmartNavigation的页面时,提交后不能显示预期的alert窗口;
    7、对一些特殊符号的提交产生bug,比如在使用SmartNavigation的页面中,如果向TextBox中写入一个“`“(按一下Esc下面那个键)开头的值。Submit后,TextBox会消失掉,在Submit一下,TextBox出现,但里面的值已经没有了;
    8、页面中写在<head>内的CSS styesheet,在第一次Submit后就会丢失,这个从1.1的SmartNavigation源代码里可以看到,他在处理<head>时,只处理了<title>和<mate>;
    9、DefaultRedirect属性不能正确执行,这个可以查看M$的KB813831
    总的说来,SmartNavigation的出现还是不错的,不过由于它真正的复杂,也同时导致了不少的问题。所以使用SmartNavigation功能一定要慎重,同时对于太复杂并内嵌大量JScript脚本的页面,就不要考虑了。

    罗嗦了半天,真正的主角还没有出场,真是失败。下面就就来看看我的“SmartNavigation“的超级瘦身减肥苗条版:
    其实也太简单了,就是记录Post时的ScrollTop,Response后在set这个ScrollTop到提交时的位置,不过我做了一个控件,拖到页面上就让该页面具有Navigate的功能了。代码如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Birdshome.Web.UI.WebControls
{
    
/// <summary>
    
/// Summary description for Class1.
    
/// </summary>

    [Designer(typeof(Birdshome.Web.UI.Design.ClientNavigationDesigner))]
    [ToolboxData(
"<{0}:ClientNavigation runat="server"></{0}:ClientNavigation>")]
    
public class ClientNavigation : WebControl, INamingContainer, IPostBackDataHandler
    
{
        
public ClientNavigation() : base() {}

        
public int Position
        
{
            
get
            
{
                
object obj = ViewState["Position"];
                
return obj == null ? 0 : (int)obj;
            }

            
set
            
{
                ViewState[
"Position"= value;
            }

        }


        
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, 
this.Position.ToString());
            writer.RenderBeginTag(HtmlTextWriterTag.Input);
            writer.RenderEndTag();
        }


        
private void RegisterClientScript()
        
{
            
const string REGISTER_KEY = "__ClientNavigate586787__";
            
string strScript = @"
                <script language=""javascript"">
                window.onload 
= function()
                
{{
                    var scrollPsn 
= {0};
                    var scrollCount 
= 0
                    
do
                    
{{
                        scrollCount 
++;
                        window.scrollTo(
0, scrollPsn);
                    }
}

                    
while(document.body.scrollTop < scrollPsn && scrollCount < 10 );
                }
}

                document.body.onscroll 
= function()
                
{{
                    document.all.
{1}.value = document.body.scrollTop;
                }
}

                
</script>";
            if ( !this.Page.IsStartupScriptRegistered(REGISTER_KEY) )
            
{
                strScript 
= String.Format(strScript, this.Position, this.ClientID);
                
this.Page.RegisterStartupScript(REGISTER_KEY, strScript);
            }

        }


        
IPostBackDataHandler Members
    }

}
    这个ClientNavigation有个问题,就是可以拖多个到一个页面,虽然不影响使用,但不知道有没有好办法能让控件只能在一个Page上最多放一个呢?

posted on 2004-09-09 02:17 birdshome 阅读(2494) 评论(8)  编辑 收藏 网摘 所属分类: Asp.net控件开发

评论

#1楼   回复  引用    

scottwater写的
http://scottwater.com/articles/ScrollPage
2004-09-09 09:01 | 活靶子正在被新蚊连啵

#2楼   回复  引用    

技术的媚外到了你这种无可复加的地步真实没意思。
不是要解释什么,这个网站你好像你已经给我介绍过了。
不要说scottwater,就是博客园好象也有类似的功能代码的。
2004-09-09 09:38 | birdshome

#3楼   回复  引用  查看    

晕,
没有媚外,
只是贴另一个方案而已,
如果引起了您的反感,我道歉,
对不起.
:)
2004-11-08 12:52 | 活靶子的靶子      

#4楼   回复  引用    

.text不就是scottwater写的吗?
2004-11-17 19:55 | robaggio

#5楼   回复  引用    

如果滚动条不是再page,而是在div里的,
又不能用了吧。
2005-04-19 20:20 | neuhawk

#6楼   回复  引用    

@neuhawk
这个需求不是通用解决方案的范畴了,如果要解决也是一个原理而已。
2005-04-19 20:41 | birdshome

#7楼   回复  引用    

我在asp.net2.0 ajax中使用SmartNavigation解决了客户端操作后丢失css文件类信息~~其实很简单~你自己去琢磨相信点就好了
2007-04-24 21:58 | 郭树灿[未注册用户]

#8楼   回复  引用    

我的QQ27048384欢迎大家一起来交流asp.net2.0技术
2007-04-24 21:59 | 郭树灿[未注册用户]



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 41235




相关文章:

相关链接: