的RegisterStartupScript和的RegisterClientScriptBlock之间的区别?区别、RegisterStartupScript、RegisterClientScript

2023-09-02 20:41:53 作者:由着我着迷

时的的RegisterStartupScript 的RegisterClientScriptBlock 是的RegisterStartupScript把javascript的结束< /表> 之后的页面标签和的RegisterClientScriptBlock把它起始<形式GT; 页面的标签?

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.

<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>

这里是code背后:

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 ,它回传,但标签颜色不会更改为红色。为什么是这样?是不是因为标签不被初始化?

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?

我也看了,如果您使用的是的UpdatePanel ,你需要使用 ScriptManager.RegisterStartupScript ,但如果我有一个母版,我会用的ScriptManagerProxy

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一个老话题在我列出的主要差异,并在其中,你应该使用这些方法的条件。我想你可能会发现它有用经过讨论。

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:

一个。当您使用的RegisterStartupScript ,它会使你的脚本的在的页面(表单的结束标记前右)的所有元素。这使得脚本调用或引用页面元素,没有它没有找到它们在页面的DOM的可能性。

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.

下面是当你调用页面的呈现源的的RegisterStartupScript 方法:

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>

乙。当您使用的RegisterClientScriptBlock ,该脚本呈现的视图状态标记之后,但在任何一个页面元素。由于这是一个直接的脚本(不是函数,可以的名为的,它会立即由​​浏览器执行,但浏览器没有找到在页面的DOM标签在这个阶段,因此你应该收到未找到对象错误。

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.

下面是当你调用页面的呈现源的的RegisterClientScriptBlock 方法:

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).

意见后编辑:

有关例如,以下功能将工作:

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); 
  } 
}