RegisterStartupScript和RegisterClientScriptBlock之间的区别?


139

是的唯一区别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吗?

Answers:


162

这是一个旧的讨论线程,在其中我列出了主要区别以及应使用每种方法的条件。我认为您可能会觉得进行讨论很有用。

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

一个。使用时RegisterStartupScript,它将在页面中的所有元素之后(在表单的end标签之前)呈现脚本。这使脚本可以调用或引用页面元素,而不会在页面的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标记之后但在任何页面元素之前呈现。由于这是直接脚本(不是可以调用的函数,因此它将被浏览器立即执行。但是在此阶段,浏览器无法在Page 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); 
  } 
} 

1
您能否进一步解释一下内联函数。
Xaisoft

2
编辑我的帖子以更好地说明您的示例。
Cerebrus

1
我实际上没有收到错误,时间更新了,但是颜色没有改变。如果我在母版页中已经定义了ScriptManager,那么我问我是否必须使用ScriptManagerProxy的问题部分呢?
Xaisoft

1
完成编辑。我不确定ScriptManagerProxy的错误。我认为您应该评估这是否不是一个单独的问题。;-)
Cerebrus 2009年

1
大!到目前为止谢谢。我没有收到ScriptManagerProxy错误。我只知道您只能声明ScriptManager的一个实例,因此,例如,如果我已经在母版页中定义了ScriptManager,那么我会假设我将改用ScriptManagerProxy。
Xaisoft

6

这是ASP.NET社区中最简单的示例,它使我对概念有了清晰的了解。

这有什么区别?

对于此示例,这是一种将页面加载到浏览器中时将焦点放在页面上的文本框上的RegisterStartupScript方法-使用Visual Basic,使用方法:

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

之所以行之有效,是因为页面上的文本框是在浏览器进入页面底部并使用JavaScript时生成并放置在页面上的。

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

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

焦点将不会到达文本框控件,并且页面上将生成JavaScript错误

原因是浏览器在页面上的文本框之前会遇到JavaScript。因此,JavaScript将无法找到TextBox1。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.