[C#] RegisterStartupScript와 RegisterClientScriptBlock의 차이점은 무엇입니까?

사이의 유일한 차이 RegisterStartupScript와는 RegisterClientScriptBlockRegisterStartupScript 닫는 전에 자바 스크립트를두고 있다는 것입니다 </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입니까?



답변

다음 은 주요 차이점과 이러한 각 방법을 사용해야하는 조건을 나열한 오래된 토론 스레드 입니다. 토론을하는 것이 도움이 될 것 같습니다.

게시 된 예제와 관련된 차이점을 설명하려면

ㅏ. 를 사용 하면 페이지의 모든 요소 뒤에 (양식의 끝 태그 바로 앞) 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);
  }
} 


답변

다음 은 ASP.NET Community 의 가장 간단한 예입니다.이 개념에 대한 명확한 이해를 제공했습니다.

이것이 어떤 차이가 있습니까?

이 예제를 보려면 다음 방법을 사용하여 Visual Basic을 사용하여 페이지를 브라우저에로드 할 때 페이지의 텍스트 상자에 포커스를 두는 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을 찾을 수 없습니다.


답변