RegisterStartupScript和RegisterClientScriptBlock之间的区别?

RegisterStartupScriptRegisterClientScriptBlock之间的唯一区别在于, RegisterStartupScript在closures页面的</form>标记之前放置了javascript,RegisterClientScriptBlock在页面的起始<form>标记后面放置了JavaScript。

另外,你什么时候select一个呢? 我写了一个快速样本页面,我有一个问题,我不知道为什么发生的确切原因。

这里是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()); } } 

问题是,当我点击btnPostBackbutton时,它会做一个回发并将标签更改为红色,但是当我单击btnPostBack2 ,它会执行回发,但标签颜色不会更改为红色。 为什么是这样? 是因为标签没有初始化?

我也读过,如果你正在使用UpdatePanel ,你需要使用ScriptManager.RegisterStartupScript ,但是如果我有一个MasterPage ,我会用ScriptManagerProxy吗?

以下是一个陈旧的讨论主题 ,列出了您应该使用这些方法的主要区别和条件。 我想你可能会发现通过讨论是有益的。

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

一个。 当您使用RegisterStartupScript ,它将在页面中的所有元素(即表单的结束标记之前) 之后呈现脚本。 这使脚本可以调用或引用页面元素,而不会在页面的DOM中find它们。

以下是调用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中find这个标签,所以你应该会收到一个“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'; 

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

评论后编辑:


例如,以下function将起作用:

 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社区的一个最简单的例子,这给了我一个清晰的概念….

这有什么不同?

举一个例子,当页面被加载到浏览器中时,下面是一个使用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将无法findTextBox1。