RegisterStartupScript 和 RegisterClientScriptBlock 之间的区别? ?

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

194650 次浏览

这里有一个旧的讨论线程 ,我在其中列出了主要的区别以及应该在哪些条件下使用这些方法。我认为你可能会发现讨论是有用的。

为了解释与你发布的例子相关的差异:

一。当您使用 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 中找到标签,因此您应该会收到一个“ Object not found”错误。

下面是调用 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);
}
}

这里有一个来自 ASP.NET 社区的 最简单的示例,它让我对这个概念有了清晰的理解... ..。

这有什么区别吗?

例如,下面是一种在页面加载到浏览器时将焦点放在页面上的文本框的方法ーー VisualBasic 使用 RegisterStartupScript方法:

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。