前两天一直在找asp.net页面加载时的loading,找了很多基本上就三种。
第一种:用Js(或ajax)来实现,在页面最上方写个div,页面加载完以后隐藏。
缺点:这种用来加载图片什么的不错,如果是后台code执行时长时就不行了,要白屏很久。
第二种: 用Response.Write + Response.Flush组成的,这种的好处如果后台bind的内容很多,第一时间会显示时度条,不会卡白屏很久。
缺点:由于.net中Response.Write是默认输出在最上方的,影响了css的显示也破坏了html的结构。如果你的代码中有操作Cookie或Response.Redirect的话,还会出错.(先Response.Flush再操作cookie或Redirect就出错误)
第三种:用Page.RegisterStartupScript + Response.Flush来做,我要对大家说,这个方法一点用都没有,和第一种其实是一样的,如果后台code时间长,依然会白屏很久,不信去(sleep(10000)试试)
我找了很久一直没有找到合适的答案,最后决定自己动手修改一下网上的代码以实现我们需要的功能。
效果:http://www.bangso.com/blog/default.aspx?bun=yeagen
/// <summary>
/// 页面加载中效果
/// </summary>
public static void initJavascript()
{
string ua = HttpContext.Current.Request.UserAgent.ToLower();
if (HttpContext.Current.Session["blog"] == null && !ua.Contains("bot") && !ua.Contains("spider") && !ua.Contains("slurp") && !ua.Contains("google") && !ua.Contains("baidu"))
{
string f = string.Empty;
f += " <script language=JavaScript type=text/javascript>";
f += "var t_id = setInterval(animate,20);";
f += "var pos=0;var dir=2;var len=0;";
f += "function animate(){";
f += "var elem = document.getElementById(\'progress\');";
f += "if(elem != null) {";
f += "if (pos==0) len += dir;";
f += "if (len>32 || pos>79) pos += dir;";
f += "if (pos>79) len -= dir;";
f += " if (pos>79 && len==0) pos=0;";
f += "elem.style.left = pos;";
f += "elem.style.width = len;";
f += "}}";
f += "</script>";
f += "<style>";
f += "#loader_container {text-align:center; position:fixed;_position:absolute; top:40%; width:100%; left: 0;}";
f += "#loader {font-family:Tahoma, Helvetica, sans; font-size:11.5px; color:#000000; background-color:#FFFFFF; padding:10px 0 16px 0; margin:0 auto; display:block; width:130px; border:1px solid #5a667b; text-align:left; z-index:2;}";
f += "#progress {height:5px; font-size:1px; width:1px; position:relative; top:1px; left:0px; background-color:#8894a8;}";
f += "#loader_bg {background-color:#e4e7eb; position:relative; top:8px; left:8px; height:7px; width:113px; font-size:1px;}";
f += "</style>";
f += "<div id=loader_container>";
f += "<div id=loader>";
f += "<div align=center>页面正在加载中 ...</div>";
f += "<div id=loader_bg><div id=progress> </div></div>";
f += "</div></div>";
HttpContext.Current.Session["blog"] = "billpeng";
HttpContext.Current.Response.Write(f + "<script>location.replace(\'" + HttpContext.Current.Request.Url.ToString() + "\');</script>");
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
else
{
HttpContext.Current.Session["blog"] = null;
}
}
#endregion
分析一下上页面的代码,其实很简单,就是先Response.write + flush输出进度条后直接Response.end,然后通过js让它再转到当前页面,通过Session来做开关,判断显示内容还是显示进度条,为防止网络蜘蛛抓取到进度页面而不是内容页,加入对useragent的判断,如果是蜘蛛就跳过进度条直接显示内容。
调用代码如下:
initJavascript();
目前存在的问题:性能上有点不是最好,要多跳转一次页面,可能实现上不够美观;只能loading解决白屏情况,一但响应到浏览器则不再loading了(不过我认为这个问题不大)。