RegisterStartupScript 和 RegisterClientScriptBlock 的区别? [英] Difference between RegisterStartupScript and RegisterClientScriptBlock?

查看:28
本文介绍了RegisterStartupScript 和 RegisterClientScriptBlock 的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RegisterStartupScriptRegisterClientScriptBlock 之间的唯一区别是 RegisterStartupScript 将 javascript 放在 </form> 结束标记之前页面和 RegisterClientScriptBlock 将它放在页面的起始 <form> 标记之后?

另外,你什么时候会选择一个?我写了一个快速示例页面,我遇到了一个问题,但我不确定它发生的确切原因.

这是 aspx 标记:

<head runat="服务器"><title></title><身体><form id="form1" runat="server"><div><asp:标签 ID="lblDisplayDate" runat="服务器"文本="标签"/><br/><asp:Button ID="btnPostback" runat="server"文本="注册启动脚本"onclick="btnPostback_Click"/><br/><asp:Button ID="btnPostBack2" runat="server"文字=注册"onclick="btnPostBack2_Click"/>

</表单>

这是背后的代码:

protected void Page_Load(object sender, EventArgs e){lblDisplayDate.Text = DateTime.Now.ToString("T");}protected void btnPostback_Click(object sender, EventArgs e){System.Text.StringBuilder sb = new System.Text.StringBuilder();sb.Append(@"<script language='javascript'>");sb.Append(@"var lbl = document.getElementById('lblDisplayDate');");sb.Append(@"lbl.style.color='red';");sb.Append(@"</script>");if(!ClientScript.IsStartupScriptRegistered("JSScript")){ClientScript.RegisterStartupScript(this.GetType(),"JSScript",sb.ToString());}}protected void btnPostBack2_Click(object sender, EventArgs e){System.Text.StringBuilder sb = new System.Text.StringBuilder();sb.Append(@"<script language='javascript'>");sb.Append(@"var lbl = document.getElementById('lblDisplayDate');");sb.Append(@"lbl.style.color='red';");sb.Append(@"</script>");if (!ClientScript.IsClientScriptBlockRegistered("JSScriptBlock")){ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScriptBlock",sb.ToString());}}

问题是当我单击 btnPostBack 按钮时,它执行回发并将标签更改为红色,但是当我单击 btnPostBack2 时,它执行回发,但标签颜色不会变为红色.为什么是这样?是不是因为标签没有初始化?

我还读到,如果您使用 UpdatePanel,则需要使用 ScriptManager.RegisterStartupScript,但如果我有一个 MasterPage,我会使用 ScriptManagerProxy 吗?

解决方案

这里是一个旧的讨论主题,我在其中列出了主要区别以及您应该使用每种方法的条件.我认为您可能会发现进行讨论很有用.

解释与您发布的示例相关的差异:

一个.当您使用 RegisterStartupScript 时,它将在页面中的所有元素之后(就在表单的结束标记之前)呈现您的脚本.这使脚本能够调用或引用页面元素,而不会在页面的 DOM 中找不到它们.

这是调用 RegisterStartupScript 方法时呈现的页面源:

<head id="Head1"><title></title></head><身体><form name="form1" method="post" action="StartupScript.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish"/>

<div><span id="lblDisplayDate">标签</span><br/><input type="submit" name="btnPostback" value="注册启动脚本" id="btnPostback"/><br/><input type="submit" name="btnPostBack2" value="Register" id="btnPostBack2"/>

<div><input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="someViewstategibberish"/>

<!-- 注意这部分--><脚本语言='javascript'>var lbl = document.getElementById('lblDisplayDate');lbl.style.color = '红色';</表单><!-- 注意这部分-->

B.当您使用 RegisterClientScriptBlock 时,脚本会在 Viewstate 标记之后呈现,但在任何页面元素之前呈现.由于这是一个直接脚本(不是一个可以调用的函数,它会立即被浏览器执行.但是在这个阶段浏览器并没有在页面的 DOM 中找到标签,因此你应该收到找不到对象"错误.

这是调用 RegisterClientScriptBlock 方法时呈现的页面源:

<head id="Head1"><title></title></head><身体><form name="form1" method="post" action="StartupScript.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish"/>

<脚本语言='javascript'>var lbl = document.getElementById('lblDisplayDate');//下一行抛出错误,因为 lbl 为空.lbl.style.color = '绿色';

因此,总而言之,如果您打算呈现函数定义,您应该调用后一种方法.然后,您可以使用前一种方法(或添加客户端属性)呈现对该函数的调用.

评论后

<小时>

例如,以下函数可以工作:

protected void btnPostBack2_Click(object sender, EventArgs e){System.Text.StringBuilder sb = new System.Text.StringBuilder();sb.Append("<script language='javascript'>function ChangeColor() {");sb.Append("var lbl = document.getElementById('lblDisplayDate');");sb.Append("lbl.style.color='green';");sb.Append("}</script>");//渲染函数定义.if (!ClientScript.IsClientScriptBlockRegistered("JSScriptBlock")){ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScriptBlock", sb.ToString());}//渲染函数调用.string funcCall = "<script language='javascript'>ChangeColor();</script>";if (!ClientScript.IsStartupScriptRegistered("JSScript")){ClientScript.RegisterStartupScript(this.GetType(), "JSScript", funcCall);}}

Is the only difference between the RegisterStartupScript and the RegisterClientScriptBlock is that RegisterStartupScript puts the javascript before the closing </form> tag of the page and RegisterClientScriptBlock puts it right after the starting <form> tag of the page?

Also, when would you choose one over the other? I wrote up a quick sample page where I had an issue and I am not sure the exact reason of why it is happening.

Here is the aspx markup:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:Label ID="lblDisplayDate" runat="server"
                           Text="Label" /><br />
                <asp:Button ID="btnPostback" runat="server" 
                            Text="Register Startup Script"
                            onclick="btnPostback_Click" /><br />
                <asp:Button ID="btnPostBack2" runat="server" 
                            Text="Register"
                            onclick="btnPostBack2_Click" />
            </div>
        </form>
    </body>
</html>

Here is the Code Behind:

protected void Page_Load(object sender, EventArgs e)
{
    lblDisplayDate.Text = DateTime.Now.ToString("T");
}

protected void btnPostback_Click(object sender, EventArgs e)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append(@"<script language='javascript'>");
    sb.Append(@"var lbl = document.getElementById('lblDisplayDate');");
    sb.Append(@"lbl.style.color='red';");
    sb.Append(@"</script>");

    if(!ClientScript.IsStartupScriptRegistered("JSScript"))
    {
        ClientScript.RegisterStartupScript(this.GetType(),"JSScript",
        sb.ToString());
    }
}

protected void btnPostBack2_Click(object sender, EventArgs e)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append(@"<script language='javascript'>");
    sb.Append(@"var lbl = document.getElementById('lblDisplayDate');");
    sb.Append(@"lbl.style.color='red';");
    sb.Append(@"</script>");

    if (!ClientScript.IsClientScriptBlockRegistered("JSScriptBlock"))
    {
        ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScriptBlock",  
        sb.ToString());
    } 
 }

The problem is when I click the btnPostBack button, it does a postback and changes the label to red, but when I click the btnPostBack2, it does a postback, but the label color does not change to red. Why is this? Is it because the label is not initialized?

I also read that if you are using an UpdatePanel, you need to use ScriptManager.RegisterStartupScript, but if I have a MasterPage, would I use ScriptManagerProxy?

解决方案

Here's an old discussion thread where I listed the main differences and the conditions in which you should use each of these methods. I think you may find it useful to go through the discussion.

To explain the differences as relevant to your posted example:

a. When you use RegisterStartupScript, it will render your script after all the elements in the page (right before the form's end tag). This enables the script to call or reference page elements without the possibility of it not finding them in the Page's DOM.

Here is the rendered source of the page when you invoke the RegisterStartupScript method:

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1"><title></title></head>
<body>
    <form name="form1" method="post" action="StartupScript.aspx" id="form1">
        <div>
            <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish" />
        </div>
        <div> <span id="lblDisplayDate">Label</span>
            <br />
            <input type="submit" name="btnPostback" value="Register Startup Script" id="btnPostback" />
            <br />
            <input type="submit" name="btnPostBack2" value="Register" id="btnPostBack2" />
        </div>
        <div>
            <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="someViewstategibberish" />
        </div>
        <!-- Note this part -->
        <script language='javascript'>
            var lbl = document.getElementById('lblDisplayDate');
            lbl.style.color = 'red';
        </script>
    </form>
    <!-- Note this part -->
</body>
</html>

b. When you use RegisterClientScriptBlock, the script is rendered right after the Viewstate tag, but before any of the page elements. Since this is a direct script (not a function that can be called, it will immediately be executed by the browser. But the browser does not find the label in the Page's DOM at this stage and hence you should receive an "Object not found" error.

Here is the rendered source of the page when you invoke the RegisterClientScriptBlock method:

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1"><title></title></head>
<body>
    <form name="form1" method="post" action="StartupScript.aspx" id="form1">
        <div>
            <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish" />
        </div>
        <script language='javascript'>
            var lbl = document.getElementById('lblDisplayDate');
            // Error is thrown in the next line because lbl is null.
            lbl.style.color = 'green';

Therefore, to summarize, you should call the latter method if you intend to render a function definition. You can then render the call to that function using the former method (or add a client side attribute).

Edit after comments:


For instance, the following function would work:

protected void btnPostBack2_Click(object sender, EventArgs e) 
{ 
  System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
  sb.Append("<script language='javascript'>function ChangeColor() {"); 
  sb.Append("var lbl = document.getElementById('lblDisplayDate');"); 
  sb.Append("lbl.style.color='green';"); 
  sb.Append("}</script>"); 

  //Render the function definition. 
  if (!ClientScript.IsClientScriptBlockRegistered("JSScriptBlock")) 
  {
    ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScriptBlock", sb.ToString()); 
  }

  //Render the function invocation. 
  string funcCall = "<script language='javascript'>ChangeColor();</script>"; 

  if (!ClientScript.IsStartupScriptRegistered("JSScript"))
  { 
    ClientScript.RegisterStartupScript(this.GetType(), "JSScript", funcCall); 
  } 
} 

这篇关于RegisterStartupScript 和 RegisterClientScriptBlock 的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
C#/.NET最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆