Loading控件--防止用户反复提交 [源码+Demo]
来源:互联网 发布:linux 设置java home 编辑:程序博客网 时间:2024/06/02 23:59
Web系统中经常会遇到这样的情况:页面提交很慢,用户耐心受到挑战就开始摧残页面上的按钮,反复点击反而搞得更慢。前两天就遇到这样一个问题,用户要进行大数据量的导出操作,这个服务器端需要比较长的时间处理,于是很容易出现用户等得不耐烦就反复点击导出按钮的情况。
比较简单的解决方法就是在用户进行了点击操作将按钮之类的东西隐藏掉,国外的一位同行写了一个对button的扩展:pleasewaitButton 源文档 <http://www.codeproject.com/KB/webforms/PleaseWaitButton.aspx> 就是实现了这个效果。但是这个控件是有局限的,有时候要隐藏的不只是按钮。我觉得可以学习UpdatePanel的“包起来”一个区域的方式以获得更大的灵活性。
下面是页面代码的一个示例:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3 <%@ Register Assembly="KingWebControlToolkit" Namespace="KingWebControlToolkit" TagPrefix="King" %>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <html xmlns="http://www.w3.org/1999/xhtml">
6 <head runat="server">
7 <title>Untitled Page</title>
8 </head>
9 <body>
10 <form id="form1" runat="server">
11 <div>
12 <King:LoadingControl runat="server">
13 <ContentTemplate>
14 <asp:Button ID="Button1" runat="server" Text="Button" />
15 </ContentTemplate>
16 <ProgressTemplate>
17 <img src="loader.gif" />Loading
18 </ProgressTemplate>
19 </King:LoadingControl>
20 </div>
21 </form>
22 </body>
23 </html>
24
2
3 <%@ Register Assembly="KingWebControlToolkit" Namespace="KingWebControlToolkit" TagPrefix="King" %>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <html xmlns="http://www.w3.org/1999/xhtml">
6 <head runat="server">
7 <title>Untitled Page</title>
8 </head>
9 <body>
10 <form id="form1" runat="server">
11 <div>
12 <King:LoadingControl runat="server">
13 <ContentTemplate>
14 <asp:Button ID="Button1" runat="server" Text="Button" />
15 </ContentTemplate>
16 <ProgressTemplate>
17 <img src="loader.gif" />Loading
18 </ProgressTemplate>
19 </King:LoadingControl>
20 </div>
21 </form>
22 </body>
23 </html>
24
为了能看到Loading的效果我们在Page_Load中使用System.Threading.Thread.Sleep(3000);做延迟。
页面render出来的代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
Untitled Page
</title></head>
<body>
<form name="form1" method="post" action="default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEzMTA5NTM4NzBkZLrTZqXsuouOmVoeCXorqE2igxmz" />
</div>
<div>
<span><span onclick="javascript:this.style.display='none';document.getElementById('progress').style.display='';" id="content">
<input type="submit" name="ctl02$Button1" value="Button" id="ctl02_Button1" />
</span><span id="progress" style="display:none">
<img src="loader.gif" />Loading
</span></span>
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLd8PGLAgLbhbjtDTVN73GhBUNr1cM8hkjWUdhLBytV" />
</div></form>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
Untitled Page
</title></head>
<body>
<form name="form1" method="post" action="default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEzMTA5NTM4NzBkZLrTZqXsuouOmVoeCXorqE2igxmz" />
</div>
<div>
<span><span onclick="javascript:this.style.display='none';document.getElementById('progress').style.display='';" id="content">
<input type="submit" name="ctl02$Button1" value="Button" id="ctl02_Button1" />
</span><span id="progress" style="display:none">
<img src="loader.gif" />Loading
</span></span>
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLd8PGLAgLbhbjtDTVN73GhBUNr1cM8hkjWUdhLBytV" />
</div></form>
</body>
</html>
控件实现
其实就两个要点:
- 控件要支持两个模板一个是ContentTemplate这个是要隐藏部分的模板,一个是Progress模板用来放Loading的提示信息
- 添加javascript脚本来实现隐藏,这个利用事件传递的原理可以方便的实现
这个控件超简单直接贴代码了,控件源代码如下:
1using System;
2using System.ComponentModel;
3using System.Drawing;
4using System.Security.Permissions;
5using System.Web;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8
9namespace KingWebControlToolkit
10{
11 [
12 AspNetHostingPermission(SecurityAction.InheritanceDemand,
13 Level = AspNetHostingPermissionLevel.Minimal),
14 AspNetHostingPermission(SecurityAction.Demand,
15 Level = AspNetHostingPermissionLevel.Minimal),
16 ToolboxData(
17 "<{0}:LoadingControl runat=/"server/"> </{0}:LoadingControl>"),
18 ]
19 public class LoadingControl : CompositeControl
20 {
21 private ITemplate contentTempalte;
22 private ITemplate progressTemplate;
23
24 private TemplateContainer contentContainer;
25 private TemplateContainer progressContainer;
26 [
27 Browsable(false),
28 DesignerSerializationVisibility(
29 DesignerSerializationVisibility.Hidden)
30 ]
31 public TemplateContainer Owner
32 {
33 get
34 {
35 return contentContainer;
36 }
37 }
38
39 [
40 Browsable(false),
41 PersistenceMode(PersistenceMode.InnerProperty),
42 DefaultValue(typeof(ITemplate), ""),
43 Description("Control template"),
44 TemplateContainer(typeof(LoadingControl ))
45 ]
46 public virtual ITemplate ContentTemplate
47 {
48 get
49 {
50 return contentTempalte;
51 }
52 set
53 {
54 contentTempalte = value;
55 }
56 }
57
58 [
59 Browsable(false),
60 PersistenceMode(PersistenceMode.InnerProperty),
61 DefaultValue(typeof(ITemplate), ""),
62 Description("Control template"),
63 TemplateContainer(typeof(LoadingControl))
64 ]
65 public virtual ITemplate ProgressTemplate
66 {
67 get
68 {
69 return progressTemplate;
70 }
71 set
72 {
73 progressTemplate = value;
74 }
75 }
76
77 protected override void CreateChildControls()
78 {
79 Controls.Clear();
80 contentContainer = new TemplateContainer();
81 progressContainer = new TemplateContainer();
82 contentContainer.Attributes["onclick"] = "javascript:this.style.display='none';document.getElementById('progress').style.display='';";
83 contentContainer.Attributes["id"] = "content";
84 progressContainer.Attributes["id"] = "progress";
85 progressContainer.Attributes["style"] = "display:none";
86 ITemplate temp = contentTempalte;
87 if (temp == null)
88 {
89 temp = new DefaultTemplate();
90 }
91 temp.InstantiateIn(contentContainer);
92
93 temp = progressTemplate;
94 temp.InstantiateIn(progressContainer);
95 this.Controls.Add(contentContainer);
96 this.Controls.Add(progressContainer);
97 }
98 }
99
100 [
101 ToolboxItem(false)
102 ]
103 public class TemplateContainer : WebControl
104 {
105 }
106
107 DefaultTemplate#region DefaultTemplate
108 sealed class DefaultTemplate : ITemplate
109 {
110 void ITemplate.InstantiateIn(Control owner)
111 {
112 LiteralControl linebreak = new LiteralControl("<br/><font size='2' color='blue' >没有制定模板内容,显示默认模板<br/>Tip:Tempalte id not defined,using default Tempalte.</font>");
113 owner.Controls.Add(linebreak);
114 }
115 }
116 #endregion
117}
118
Demo下载:http://files.cnblogs.com/me-sa/loadingdemo.rar
2using System.ComponentModel;
3using System.Drawing;
4using System.Security.Permissions;
5using System.Web;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8
9namespace KingWebControlToolkit
10{
11 [
12 AspNetHostingPermission(SecurityAction.InheritanceDemand,
13 Level = AspNetHostingPermissionLevel.Minimal),
14 AspNetHostingPermission(SecurityAction.Demand,
15 Level = AspNetHostingPermissionLevel.Minimal),
16 ToolboxData(
17 "<{0}:LoadingControl runat=/"server/"> </{0}:LoadingControl>"),
18 ]
19 public class LoadingControl : CompositeControl
20 {
21 private ITemplate contentTempalte;
22 private ITemplate progressTemplate;
23
24 private TemplateContainer contentContainer;
25 private TemplateContainer progressContainer;
26 [
27 Browsable(false),
28 DesignerSerializationVisibility(
29 DesignerSerializationVisibility.Hidden)
30 ]
31 public TemplateContainer Owner
32 {
33 get
34 {
35 return contentContainer;
36 }
37 }
38
39 [
40 Browsable(false),
41 PersistenceMode(PersistenceMode.InnerProperty),
42 DefaultValue(typeof(ITemplate), ""),
43 Description("Control template"),
44 TemplateContainer(typeof(LoadingControl ))
45 ]
46 public virtual ITemplate ContentTemplate
47 {
48 get
49 {
50 return contentTempalte;
51 }
52 set
53 {
54 contentTempalte = value;
55 }
56 }
57
58 [
59 Browsable(false),
60 PersistenceMode(PersistenceMode.InnerProperty),
61 DefaultValue(typeof(ITemplate), ""),
62 Description("Control template"),
63 TemplateContainer(typeof(LoadingControl))
64 ]
65 public virtual ITemplate ProgressTemplate
66 {
67 get
68 {
69 return progressTemplate;
70 }
71 set
72 {
73 progressTemplate = value;
74 }
75 }
76
77 protected override void CreateChildControls()
78 {
79 Controls.Clear();
80 contentContainer = new TemplateContainer();
81 progressContainer = new TemplateContainer();
82 contentContainer.Attributes["onclick"] = "javascript:this.style.display='none';document.getElementById('progress').style.display='';";
83 contentContainer.Attributes["id"] = "content";
84 progressContainer.Attributes["id"] = "progress";
85 progressContainer.Attributes["style"] = "display:none";
86 ITemplate temp = contentTempalte;
87 if (temp == null)
88 {
89 temp = new DefaultTemplate();
90 }
91 temp.InstantiateIn(contentContainer);
92
93 temp = progressTemplate;
94 temp.InstantiateIn(progressContainer);
95 this.Controls.Add(contentContainer);
96 this.Controls.Add(progressContainer);
97 }
98 }
99
100 [
101 ToolboxItem(false)
102 ]
103 public class TemplateContainer : WebControl
104 {
105 }
106
107 DefaultTemplate#region DefaultTemplate
108 sealed class DefaultTemplate : ITemplate
109 {
110 void ITemplate.InstantiateIn(Control owner)
111 {
112 LiteralControl linebreak = new LiteralControl("<br/><font size='2' color='blue' >没有制定模板内容,显示默认模板<br/>Tip:Tempalte id not defined,using default Tempalte.</font>");
113 owner.Controls.Add(linebreak);
114 }
115 }
116 #endregion
117}
118
Demo下载:http://files.cnblogs.com/me-sa/loadingdemo.rar
- Loading控件--防止用户反复提交 [源码+Demo]
- Loading控件--防止用户反复提交 [源码+Demo]
- Loading控件--防止用户反复提交
- ajax 防止用户反复提交
- 防止反复提交窗体(PHP)
- 防止控件被反复点击
- 防止控件被反复点击
- struts2拦截非法字符+防止反复提交
- demo - loading开源控件
- html中 如何使用 Javascript 实现防止表单反复提交
- session防止表单反复提交,php让ajax跨域
- 防止用户外部提交表单
- 防止用户表单重复提交
- 如何防止用户重复提交
- 等待提交页面防止用户重复提交
- github中添加一个.gitignore忽略文件,防止一些没有用的文件反复提交
- 上传图片类型限制和防止反复提交,php递归删除空文件夹
- 如何防止用户重复提交数据
- Tcl为F5 LTM编写iRule
- 回头再说-006 时间&音乐
- [译]SSO解决方案大全 Single Sign-On for everyone
- Interaction design pattern
- 控制反转容器&依赖注入模式
- Loading控件--防止用户反复提交 [源码+Demo]
- 复用:设计模式 反模式 分析模式
- 再战浏览器兼容
- 扩展Nlog Layout Renderer原理、Demo、 工具下载
- 我回来了
- 胡乱读书去也
- Adapter Façade Decorator 与OO设计原则
- 回头再说 005 --温暖的文字和音乐
- 工厂模式与OO设计原则