RegisterStartupScript ve RegisterClientScriptBlock arasındaki fark nedir?


139

Arasındaki tek fark var mı RegisterStartupScriptve RegisterClientScriptBlockRegisterStartupScript kapanış önce javascript koyar yani </form>doğru başladıktan sonra sayfa ve RegisterClientScriptBlock koyar etiketi <form>sayfadaki etiketinin?

Ayrıca, birini diğerinden ne zaman seçersiniz? Bir sorun yaşadığım hızlı bir örnek sayfa yazdım ve bunun nedeninin tam nedeninden emin değilim.

İşte aspx işaretlemesi:

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

İşte Arkasındaki Kod:

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

Sorun, btnPostBackdüğmeyi tıklattığımda, bir geri gönderme yapıyor ve etiketi kırmızıya btnPostBack2çeviriyor, ancak tıkladığımda bir geri gönderme yapıyor, ancak etiket rengi kırmızıya değişmiyor. Bu neden? Etiket başlatılmadığı için mi?

Ben de bir kullanıyorsanız okumuştum UpdatePanel, kullanılan gerekir ScriptManager.RegisterStartupScript, ama varsa MasterPage, ben kullanırım ScriptManagerProxy?

Yanıtlar:


162

İşte ana farklılıkları ve bu yöntemlerin her birini kullanmanız gereken koşulları listelediğim eski bir tartışma dizisi . Tartışmadan geçmenin faydalı olabileceğini düşünüyorum.

Gönderilen örneğinizle ilgili farklılıkları açıklamak için:

a. Kullandığınızda RegisterStartupScript, komut dosyanızı sayfanın tüm öğelerinden sonra (formun bitiş etiketinden hemen önce) oluşturur. Bu, komut dosyasının Sayfanın DOM'sinde bulunma olasılığı olmadan sayfa öğelerini çağırmasını veya bunlara başvurmasını sağlar.

RegisterStartupScriptYöntemi çağırdığınızda sayfanın işlenen kaynağı :

<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. Kullandığınızda RegisterClientScriptBlock, komut dosyası Viewstate etiketinden hemen sonra, ancak sayfa öğelerinden herhangi birinden önce oluşturulur. Bu doğrudan bir komut dosyası olduğundan ( çağrılabilecek bir işlev değil , tarayıcı tarafından hemen yürütülür. Ancak tarayıcı bu aşamada Sayfanın DOM'sinde etiketi bulamaz ve bu nedenle bir "Nesne bulunamadı" hata.

RegisterClientScriptBlockYöntemi çağırdığınızda sayfanın işlenen kaynağı :

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

Bu nedenle, özetlemek gerekirse, bir işlev tanımı oluşturmak istiyorsanız ikinci yöntemi çağırmalısınız. Daha sonra , önceki yöntemi kullanarak bu işleve çağrı yapabilirsiniz (veya bir istemci tarafı özniteliği ekleyebilirsiniz).

Yorumlardan sonra düzenle:


Örneğin, aşağıdaki işlev işe yarar:

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
Satır içi işlevler hakkında biraz daha bilgi verebilir misiniz?
Xaisoft

2
Örneğinize göre daha iyi göstermek için yayımı düzenleme.
Cerebrus

1
Aslında bir hata almıyorum, zaman güncelleniyor, ancak renk değişmiyor. Sorumun ana sayfasında zaten tanımlanmış bir ScriptManager varsa ScriptManagerProxy kullanmak zorunda olup olmadığını sorduğum kısmı ne olacak?
Xaisoft

1
Düzenleme tamamlandı. ScriptManagerProxy ile ilgili hatadan emin değilim. Bunun gerçekten ayrı bir soru olup olmadığını değerlendirmeniz gerektiğini düşünüyorum. ;-)
Cerebrus

1
Harika! Şimdiye kadar teşekkürler. ScriptManagerProxy ile ilgili bir hata almıyorum. Sadece bir ScriptManager örneğini bildirebileceğini biliyorum, bu yüzden zaten bir ana sayfada tanımlanmış bir ScriptManager varsa, bunun yerine ScriptManagerProxy kullanacağımı varsayalım.
Xaisoft

6

İşte ASP.NET Topluluğunun en basit örneği, bu bana kavram hakkında net bir anlayış verdi ....

bu ne fark eder?

Bunun bir örneği için, sayfa tarayıcıya yüklendiğinde sayfadaki metin kutusuna odaklanmanın bir yolu şudur RegisterStartupScript: Visual Basic yöntemini kullanarak :

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

Sayfadaki metin kutusu, tarayıcı sayfanın en altına inip bu küçük JavaScript'e ulaştığında sayfaya yerleştirildiği için işe yarar.

Ancak, bunun yerine bu şekilde yazıldıysa ( RegisterClientScriptBlockyöntemi kullanarak ):

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

Odak, metin kutusu denetimine ulaşmayacak ve sayfada bir JavaScript hatası oluşturulacak

Bunun nedeni, metin kutusu sayfada olmadan önce tarayıcının JavaScript ile karşılaşmasıdır. Bu nedenle, JavaScript bir TextBox1 bulamaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.