c# - RegisterStartupScript 和 RegisterClientScriptBlock 的区别?

标签 c# javascript asp.net .net

RegisterStartupScript之间的唯一区别和 RegisterClientScriptBlock是 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

最佳答案

Here's an old discussion thread我在其中列出了主要区别以及您应该使用每种方法的条件。我想您可能会发现完成讨论很有用。

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

一个。当您使用 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>

当您使用 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); 
  } 
} 

关于c# - RegisterStartupScript 和 RegisterClientScriptBlock 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/666519/

相关文章:

c# - 用于解析的 XML 类

c# - 用服务器数组填充jquery数组?

asp.net - Instagram API 无需身份验证

c# - 使用内连接和左外连接将 6 个表连接在一起 - LINQ

javascript - AngularJS 模块名称作为常量

javascript - 想要在 jQuery Mobile 首次加载时显示对话框消息

javascript - 使用 Javascript 扩展背景

asp.net - 使用 Azure Blob 存储中的 ascx 文件

.net - ASP.NET 验证码实现

c# - 我们如何在 C# 应用程序中运行 Javascript?