冰火
考虑老鸟问题的菜鸟
ClientScript.RegisterStartupScript:
http://msdn.microsoft.com/zh-cn/library/system.web.ui.clientscriptmanager.registerstartupscript(v=vs.80)
ClientScript.RegisterClientScriptBlock:
http://msdn.microsoft.com/zh-cn/library/system.web.ui.clientscriptmanager.registerclientscriptblock(v=vs.80).aspx
ASP.NET中,可以使用这两个方法从后台向前台注册JavaScript脚本;
这两个方法,各自都有两个重载的版本,个人推荐始终使用四个参数的版本,本文基于四个参数的版本:
public void RegisterStartupScript(Type type, string key, string script, bool addScriptTags);
public void RegisterClientScriptBlock(Type type, string key, string script, bool addScriptTags);
如果addScriptTags==true,那么script会被包含在<script></script>元素块中;
如果addScriptTags==false,此时这两个方法相当于三个参数的版本,<script></script>元素块需自己写;
另外,如果想通过注册脚本的方式,在页面上输出html元素(如<h1>标题</h1>),可以把addScriptTags设置为false,在script中写html元素,例如:
ClientScript.RegisterClientScriptBlock(Page.GetType(), "write", "<h1>标题一</h1>", false);
当然了,不推荐这种做法了,因为太不灵活了,RegisterClientScriptBlock写的html元素只能在页面的顶部,RegisterStartupScript写的html元素只能在页面的底部;比较灵活的做法是,使用JavaScript操作DOM元素。
好了,来说说RegisterClientScriptBlock和RegisterStartupScript的不同点吧:

1. RegisterClientScriptBlock注册的脚本在<form>元素的后面,而RegisterStartupScript注册的脚本在</form>元素的前面:
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ClientScript.RegisterClientScriptBlock(Page.GetType(), "", "alert('RegisterClientScriptBlock');", true);
        ClientScript.RegisterStartupScript(Page.GetType(), "", "alert('RegisterStartupScript');", true);
    }
}
生成的html:
<form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZFL5WzOc4Lk3midVVH7bOliUF/+AQZAXgy6DDne32SJ1" />
</div>
 
<script type="text/javascript"> 
//<![CDATA[
alert('RegisterClientScriptBlock');//]]>
</script>
 
    <div>
    </div>
 
<script type="text/javascript"> 
//<![CDATA[
alert('RegisterStartupScript');//]]>
</script>
</form>
生成的html源代码清楚的展现了注册的脚本在页面上的位置;
说明:生成的html源代码中,紧跟在<form>后,在RegisterClientScriptBlock注册的脚本前的内容(可能还有其他的),是ASP.NET为了实现自身功能所必须的由系统自动生成的,如果撇开这些内容,可以认为RegisterClientScriptBlock生成的脚本是紧跟在<form>元素后的。

2. 因为RegisterClientScriptBlock与RegisterStartupScript注册的脚本的位置不同,导致两者使用的场合也有所不同:
1> RegisterClientScriptBlock注册的脚本是在DOM元素未完全加载前执行的,这就导致了,它无法访问页面中几乎所有的html元素;所以RegisterClientScriptBlock适合写JavaScript函数、警告(在用户点击“确定”之前,页面为空白);
2> RegisterStartupScript注册的脚本也是在DOM元素未完全加载前执行的,可是与RegisterClientScriptBlock不同的是,页面上的大部分DOM元素它都可以访问;所以RegisterStartupScript不太适合写JavaScript函数,可能调用它写的函数的时候,函数还没加载到页面上呢;
RegisterStartupScript也可以用来写警告,此时,即使用户没有点击“确定”按钮,也可以看到页面的内容;
※ 关于RegisterStartupScript写的警告(alert),如果</form>后面有JavaScript脚本(直接硬编码在页面上的),且此脚本是控制页面呈现样式的,那么在用户点击警告框中的“确定”按钮前,页面的呈现可能会非预期;

3. 如果注册的脚本的执行依赖于页面上的元素,或为了显示出预期的效果(上面提到的用户未点击“确定”按钮,页面呈现非预期),可以结合window.onload事件,如果使用了JQuery,可以把脚本包含在:
$(document).ready(function() {
// 这里
});

4. 最后说一下RegisterStartupScript和RegisterClientScriptBlock函数的第二个参数key吧:
在页面加载或处理请求的过程中,执行了若干次RegisterStartupScript和RegisterClientScriptBlock方法,如果没有给该函数指定key,即key="",或key重复,因为相同key的脚本只会注册一次,重复注册的脚本会被忽略,如果出现了某些脚本未注册的情况,此时就需要检查是否出现了重复的key;RegisterStartupScript和RegisterClientScriptBlock的key可以重复,因为是不同的方法嘛!~
可以通过:
public bool IsStartupScriptRegistered(Type type, string key);
public bool IsClientScriptBlockRegistered(Type type, string key);
来检查是否注册了相应key的脚本,避免重复注册:
ClientScript.RegisterStartupScript(Page.GetType(), "alert", "alert('RegisterStartupScript');", true);
if (!ClientScript.IsStartupScriptRegistered(Page.GetType(), "alert"))
{
    ClientScript.RegisterStartupScript(Page.GetType(), "alert", "alert('RegisterStartupScript_2');", true);
}
上面的示例只是为了讲解IsStartupScriptRegistered的用法,实际使用中,没有谁会写这么小白的用法!~
如果可以保证在页面加载或处理请求的过程中,只会调用一次RegisterStartupScript和RegisterClientScriptBlock方法,可以不指定key;
例如,处理表单数据,某个字段不符合要求时,提示:
if (string.IsNullOrEmpty(txtInput.Value.Trim()))
{
    ClientScript.RegisterStartupScript(Page.GetType(), "", "alert('不可以为空!');", true);
    return;
}
posted on 2012-04-30 03:55  剑过不留痕  阅读(8485)  评论(0编辑  收藏  举报