
3.10 另一种解法:RegisterClientScriptBlock函数
ScriptManager控件仿照Page的ClientScript属性,提供了对应的函数,可以由被加载者来决定绘制哪些Script。以第3.8 节的例子来说,设计师可在UserControl中调用ScriptManager. RegisterClientScriptBlock函数(为程序3-24所示)来刷新,同时绘制指定的JavaScript。
程序3-24
Samples\3\AjaxDemo1\DynamicLoadUserControl3.aspx.cs protected void Page_Load(object sender, EventArgs e) { ScriptManager.RegisterClientScriptBlock(this, GetType(),"ShowMessageScript", "function showMessage(str) { alert(str); }", true); }
除了RegisterClientScriptBlock函数外,ScriptManager几乎实现了所有于Page的ClientScript属性可调用的相关Script函数,见表3-2。
表3-2

每个ScriptManager所提供的注册JavaScript的同名函数都有两个重载函数,一个以Page对象作为第一个参数,另一个则以Control对象作为第一个参数,两者的差别请见表3-3。
表3-3

一般来说,第二个以Page作为第一参数的函数是较常用的,以Control作为参数的函数多半只应用于撰写控件时,两类函数都会以第二个Type参数加上指定的键值(第三个参数)作为判断该JavaScript是否已经输出的条件,当以同一Type、同一键值注册时,将只会输出第一次调用时所注册的JavaScript程序代码。程序3-25 是一个使用RegisterStartupScript函数注册JavaScript程序代码,在点击按钮产生Async-Postback后跳出一信息的例子,其运行结果如图3-20所示。

图3-20
程序3-25
.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode=conditional runat= "server"> <ContentTemplate> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> .aspx.cs using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { ScriptManager.RegisterStartupScript(this, typeof(Page), "MyScript", "alert('Hello!!');", true); } }
不知读者是否发现,本节的例子在你点击按钮后,该UserControl会立即消失,这是因为Postback后,动态加载的控件必须重载一次,而此处尚未重载所致,第4章会详细讨论如何解决此问题。
动态加载的JavaScript
虽然动态输出JavaScript相当好用,但聪明的你一定会很好奇,如果一直点击按钮,是不是会一直注册这段JavaScript程序代码到浏览器中运行呢?你的猜想是对的,浏览器只提供了动态加载JavaScript程序代码的能力,但没有提供释放的机制,这意味着任何使用ScriptManager加载的JavaScript程序文件或程序代码,都会一直存在于浏览器中。即使如此,使用ScriptManager处理JavaScript仍然是不可避免的,因为这是唯一可以在部分刷新情况下仍能动态输出JavaScript及运行的途径!