RegisterClientScriptBlock 的改进






4.76/5 (32投票s)
在 ASP.NET 页面和控件中注册客户端 JavaScript 的一种更简单、更灵活的方法。
引言
在编写 Web 应用程序时,让我非常头疼的一件事就是如何在保持生成的 HTML 整洁的同时,对代码进行模块化。特别是,当页面中的各个代码模块各自渲染自己的 JavaScript 时,通常会导致页面中包含许多不同且不相关的脚本片段,并且没有特定的顺序。如果 JavaScript 出现在页面的 HEAD
标签内(在合适的情况下)会很好,但 ASP 3.0 没有提供简单的解决方案。
ASP.NET 以 Page
类中的 RegisterClientScriptBlock
方法的形式,提供了一种(某种程度上的)解决方案。该方法允许您注册客户端脚本块,这些脚本块将在页面呈现时,集中地输出到页面中。我说它是一种“某种程度上的”解决方案,是因为虽然这是一个不错的想法,但它并不总是能达到您所期望的效果。
至少对我来说,RegisterClientScriptBlock
方法存在的问题是,脚本会在 ASP.NET 页面的打开 Form
标签之后输出。如果您的页面中没有这样的标签怎么办?如果您希望脚本在 HEAD 部分输出怎么办?该方法还要求您包含 <script>
标签。对我来说,这意味着大量重复的样板代码,并且容易出错。我想找一种方法,能够轻松地从页面创建逻辑中的许多不同点以及页面中包含的控件中包含脚本。我还想要一种方法,可以在可能的情况下自动填充样板代码。
您的网页的新基类。
由于 ASP.NET 提供了从您希望的任何 System.Web.UI.Page
派生类派生页面的能力,因此无疑将有大量的网页基类可用。我本可以选择将所需的功能封装在一个单独的实用类中,然后由您自己的 System.Web.UI.Page
派生类实例化并调用,但我很懒,所以这项工作就留给读者完成了。
我创建了一个简单的类 ScriptPage
,它派生自 System.Web.UI.Page
,后续页面可以从此派生。可用的方法是:
RegisterClientScriptBlock
注册一个客户端 JavaScript 块。该块会自动用 <script> 标签包围。
void RegisterClientScriptBlock(string key, string script)
void RegisterClientScriptBlock(string key, string script, string language)
void RegisterClientScriptBlock(string key, string script, string language,
bool defer)
参数
key - 脚本密钥。如果使用此密钥已注册一个脚本文件,则会替换之前的脚本。
script - 要包含的 JavaScript。
language - 脚本的语言。默认为“Javascript”。
defer - 脚本是否应在页面完全加载后运行。默认为 false。
RegisterClientScriptFile
注册一个客户端 JavaScript 文件引用。
void RegisterClientScriptFile(string key, string file)
void RegisterClientScriptFile(string key, string file, string language)
void RegisterClientScriptFile(string key, string file, string language,
bool defer)
参数
key - 脚本密钥。如果使用此密钥已注册一个脚本文件,则会替换之前的脚本。
file - 要引用的 JavaScript 包含文件。
language - 脚本的语言。默认为“Javascript”。
defer - 脚本是否应在页面完全加载后运行。默认为 false。
RegisterClientScriptEvent
void RegisterClientScriptEvent(string key, string eventName, string ctrlName,
string script)
void RegisterClientScriptEvent(string key, string eventName, string ctrlName,
string script, string language)
注册一个客户端 JavaScript 事件处理程序。仅为 IE 4.0 及更高版本呈现。
参数
key - 脚本密钥。如果使用此密钥已注册一个脚本文件,则会替换之前的脚本。
eventName - 要处理的事件。
ctrlName - 要应用此处理程序的 HTML 元素(s) 的名称。
script - 要运行的脚本。
language - 脚本的语言。默认为“Javascript”。
IsClientScriptRegistered
如果脚本块已注册,则返回 true;否则返回 false。
public bool IsClientScriptRegistered(string key)
参数
key - 要检查的脚本密钥。
使用该类
使用该类很简单。
- 将 ScriptPage.cs 文件包含在您的项目中。
- 让您的页面派生自
CodeProject.ScriptPage
而不是System.Web.UI.Page
。namespace CodeProject { /// <summary> /// Summary description for WebForm1. /// </summary> public class WebForm1 : CodeProject.ScriptPage { ...
- 在您的页面中,您希望脚本呈现的位置包含一个名为
_clientScript
的 ASP.NET Literal 控件。这可以位于页面中的任何位置,但推荐放在<HEAD>
部分内。<HTML> <HEAD> <title>WebForm1</title> <asp:literal id="_clientScript" runat="server"></asp:literal> </HEAD> <body> <form id=Form1 ...
重要提示: 如果不包含此控件,JavaScript 将不会呈现。
注意:Visual Studio .NET 中的设计器会在您以设计模式编辑页面时,在您的代码隐藏类中添加以下行:
protected System.Web.UI.WebControls.Literal _clientScript;
如果发生这种情况,您需要手动从代码隐藏文件中删除此行。
- 要从页面中注册一些 JavaScript,只需调用基类的方法即可。
private void Page_Load(object sender, System.EventArgs e) { // Let's add some javascript RegisterClientScriptBlock("Script1", "alert(\"Script1 called\");"); RegisterClientScriptFile("Script2", "MyScripts.js", "Javascript 1.2"); RegisterClientScriptEvent("Script3", "onclick", "MyButton", "alert(\"Script3 called\");"); }
- 要从用户控件或自定义控件中注册 JavaScript,只需将父页面转换为基类,然后再次调用基类的方法即可。
CodeProject.ScriptPage basePage = Page as CodeProject.ScriptPage; if (basePage != null) basePage.RegisterClientScriptBlock("Script4", "document.getElementById(\"MyTable\").style.backgroundColor='#ff9900';", "Javascript", true);
结果
请看下面的页面,它包含一个简单的表单和一个简单的用户控件。表单和用户控件都将按照上述描述注册一些 JavaScript。
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="CodeProject.WebForm1"
enableViewState="False" Trace="False"%>
<%@ Register TagPrefix="CP" TagName="WebUserControl1"
Src="WebUserControl1.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<asp:literal id="_clientScript" runat="server"></asp:literal>
</HEAD>
<body>
<form id=Form1 method=post runat="server">
<p>This is a very simple webpage. Click 'View Source' to
see the Javascript embedded within this page.
<P><input type=button id=MyButton name=MyButton value="Click me"></P>
<CP:WebUserControl1 id=WebUserControl11 runat="server"></CP:WebUserControl1>
</form>
</body>
</HTML>
呈现时的输出如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<script type="text/javascript" language="Javascript 1.2"
src="MyScripts.js">
</script>
<script type="text/javascript" language="Javascript"><!--
alert("Script1 called");
--></script>
<script type="text/javascript" language="Javascript" defer="true"><!--
document.getElementById("MyTable").style.backgroundColor = '#ff9900';
--></script>
<script type="text/javascript" language="Javascript" for="MyButton"
event="onclick" defer="true"><!--
alert("Script3 called");
//--></script>
</HEAD>
<body>
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
<p>This is a very simple webpage. Click 'View Source' to
see the Javascript embedded within this page.
<P><input type=button id=MyButton name=MyButton value="Click me"></P>
<table id=MyTable name=MyTable border=1 width=200 height=60
bgcolor=grey>
<tr><td align=center valign=middle><font size=2 face=verdana>This
is a User Control</font></td></tr>
</table>
</form>
</body>
</HTML>