RegisterStartupScriptとRegisterClientScriptBlockの違いは何ですか?


139

間の唯一の違いですRegisterStartupScriptRegisterClientScriptBlockRegisterStartupScriptを閉じる前に、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ますか?

回答:


162

これは古いディスカッションスレッドで、主な違いと、これらの各メソッドを使用する必要がある条件をリストしました。ディスカッションを進めることは役立つと思います。

投稿した例に関連する違いを説明するには:

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); 
  } 
} 

1
インライン関数についてもう少し説明してください。
Xaisoft 2009年

2
あなたの例に対してそれをよりよく説明するために私の投稿を編集します。
セレブラス2009年

1
エラーは発生しませんが、時間は更新されますが、色は変わりません。マスターページでScriptManagerが既に定義されている場合にScriptManagerProxyを使用する必要があるかどうかを尋ねる私の質問の部分はどうですか?
Xaisoft 2009年

1
編集完了。ScriptManagerProxyのエラーについてはわかりません。それが本当に別の問題ではないかどうかを評価する必要があると思います。;-)
セレブラス2009年

1
すごい!今までありがとう。ScriptManagerProxyでエラーが発生しません。ScriptManagerのインスタンスは1つしか宣言できないことを知っているので、たとえば、マスターページでScriptManagerが既に定義されている場合は、代わりにScriptManagerProxyを使用すると想定します。
Xaisoft 2009年

6

ここだ最も簡単な 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はTextBox1を見つけることができません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.