RegisterStartupScript和RegisterClientScriptBlock之间的区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (105)

RegisterStartupScriptRegisterClientScriptBlock是RegisterStartupScript将javascript放在关闭之前</form>标记和RegisterClientScriptBlock将其放在启动之后。<form>页面的标签?

下面是ASPX标记:

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

以下是守则背后的内容:

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?

提问于
用户回答回答于

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

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

下面是在调用RegisterStartupScript方法:

<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.当你使用RegisterClientScriptBlock,脚本就在ViewState标记之后呈现,但在任何页面元素之前呈现。因为这是一个直接脚本(不是一个可以,它将立即由浏览器执行。但是浏览器在这个阶段找不到页面DOM中的标签,因此您应该会收到一个“对象未找到”错误。

下面是在调用RegisterClientScriptBlock

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

因此,总之,如果要呈现函数定义,则应该调用后一种方法。然后,可以呈现调用该函数使用前一种方法(或添加客户端属性)。

例如,以下功能可以工作:

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); 
  } 
} 
用户回答回答于

对于这方面的示例,这里有一种方法可以在页面加载到浏览器时将焦点放在页面上的文本框上--使用VisualBasic使用RegisterStartupScript方法:

Page.ClientScript.RegisterStartupScript(Me.GetType(), "Testing", _ 
"document.forms[0]['TextBox1'].focus();", True)

这样做很好,因为当浏览器到达页面底部并到达这一点JavaScript时,页面上的TextBox已经生成并放置在页面上。

但是,如果它是这样编写的(使用RegisterClientScriptBlock方法):

Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "Testing", _
"document.forms[0]['TextBox1'].focus();", True)

焦点不会到达TextBox控件,并且会在页面上生成JavaScript错误

原因是浏览器会在文本框出现在页面之前遇到JavaScript。因此,JavaScript将无法找到TextBox 1。

扫码关注云+社区