137 votes

Différence entre RegisterStartupScript et RegisterClientScriptBlock ?

La seule différence entre les RegisterStartupScript et le RegisterClientScriptBlock est que RegisterStartupScript place le javascript avant la fermeture de l'écran. </form> de la page et RegisterClientScriptBlock le place juste après la balise de démarrage <form> de la page ?

Par ailleurs, quand choisiriez-vous l'un plutôt que l'autre ? J'ai rédigé une page d'exemple rapide où j'ai rencontré un problème et je ne suis pas sûr de la raison exacte pour laquelle cela se produit.

Voici la balise 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>

Voici le Code Behind :

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

Le problème est que lorsque je clique sur le bouton btnPostBack il effectue un postback et change l'étiquette en rouge, mais lorsque je clique sur le bouton btnPostBack2 Il effectue un postback, mais la couleur de l'étiquette ne passe pas au rouge. Comment cela se fait-il ? Est-ce parce que l'étiquette n'est pas initialisée ?

J'ai également lu que si vous utilisez un UpdatePanel vous devez utiliser ScriptManager.RegisterStartupScript mais si j'ai un MasterPage J'utiliserais donc ScriptManagerProxy ?

158voto

Cerebrus Points 18045

Voici un ancien fil de discussion où j'ai énuméré les principales différences et les conditions dans lesquelles il convient d'utiliser chacune de ces méthodes. Je pense qu'il vous sera utile de reprendre cette discussion.

Expliquer les différences par rapport à l'exemple que vous avez donné :

a. Lorsque vous utilisez RegisterStartupScript il rendra votre script. après tous les éléments de la page (juste avant la balise de fin de formulaire). Cela permet au script d'appeler ou de référencer des éléments de la page sans risque de ne pas les trouver dans le DOM de la page.

Voici le rendu de la source de la page lorsque vous invoquez la commande RegisterStartupScript méthode :

<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. Lorsque vous utilisez RegisterClientScriptBlock Le script est rendu juste après la balise Viewstate, mais avant tout élément de la page. Comme il s'agit d'un script direct (et non d'une fonction qui peut être appelé il sera immédiatement exécuté par le navigateur. Mais le navigateur ne trouve pas l'étiquette dans le DOM de la page à ce stade et vous devriez donc recevoir une erreur "Object not found" (objet non trouvé).

Voici le rendu de la source de la page lorsque vous invoquez la commande RegisterClientScriptBlock méthode :

<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';

Par conséquent, pour résumer, vous devez appeler cette dernière méthode si vous avez l'intention de rendre une définition de fonction. Vous pouvez alors rendre la appel à cette fonction en utilisant la première méthode (ou en ajoutant un attribut côté client).

Modifier après les commentaires :


Par exemple, la fonction suivante fonctionnerait :

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

6voto

c-sharp user Points 63

Voici une le plus simple de la communauté ASP.NET, cela m'a permis de bien comprendre le concept....

quelle différence cela fait-il ?

A titre d'exemple, voici une façon de mettre l'accent sur une zone de texte d'une page lorsque la page est chargée dans le navigateur - avec Visual Basic en utilisant l'option RegisterStartupScript méthode :

Page.ClientScript.RegisterStartupScript(Me.GetType(), "Testing", _ 
"document.forms[0]['TextBox1'].focus();", True)

Cela fonctionne bien parce que la zone de texte sur la page est générée et placée sur la page au moment où le navigateur arrive au bas de la page et à ce petit bout de JavaScript.

Mais si, au lieu de cela, il était écrit comme ceci (en utilisant l'élément RegisterClientScriptBlock ) :

Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "Testing", _
"document.forms[0]['TextBox1'].focus();", True)

L'accent ne sera pas mis sur le contrôle de la boîte de texte et une erreur JavaScript sera générée sur la page.

La raison en est que le navigateur rencontrera le JavaScript avant que la zone de texte ne soit sur la page. Par conséquent, le JavaScript ne sera pas en mesure de trouver une TextBox1.

-2voto

shruti Points 19

Lorsque nous utilisons une MasterPage, nous devons utiliser un proxy de gestionnaire script sur notre page, car il ne peut y avoir qu'un seul gestionnaire script. La pratique consiste donc à conserver le scriptmanager dans le master et à utiliser le proxy dans les pages individuelles. J'espère que cela répond à votre question.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X