Perbedaan antara RegisterStartupScript dan RegisterClientScriptBlock?

139

Apakah satu-satunya perbedaan antara RegisterStartupScriptdan RegisterClientScriptBlockadalah bahwa RegisterStartupScript menempatkan javascript sebelum </form>tag penutup halaman dan RegisterClientScriptBlock menempatkannya tepat setelah <form>tag awal halaman?

Juga, kapan Anda akan memilih satu dari yang lain? Saya menulis halaman contoh cepat di mana saya memiliki masalah dan saya tidak yakin alasan pasti mengapa itu terjadi.

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

Inilah Kode Di Baliknya:

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

Masalahnya adalah ketika saya mengklik btnPostBacktombol, itu melakukan postback dan mengubah label menjadi merah, tetapi ketika saya mengklik btnPostBack2, itu postback, tetapi warna label tidak berubah menjadi merah. Kenapa ini? Apakah karena labelnya tidak diinisialisasi?

Saya juga membaca bahwa jika Anda menggunakan UpdatePanel, Anda harus menggunakan ScriptManager.RegisterStartupScript, tetapi jika saya punya MasterPage, apakah saya akan menggunakan ScriptManagerProxy?

Xaisoft
sumber

Jawaban:

162

Inilah utas diskusi lama tempat saya mencantumkan perbedaan utama dan kondisi di mana Anda harus menggunakan masing-masing metode ini. Saya pikir Anda mungkin merasa berguna untuk pergi melalui diskusi.

Untuk menjelaskan perbedaan yang relevan dengan contoh yang Anda posting:

Sebuah. Saat Anda menggunakan RegisterStartupScript, itu akan membuat skrip Anda setelah semua elemen di halaman (tepat sebelum tag akhir formulir). Ini memungkinkan skrip untuk memanggil atau merujuk elemen halaman tanpa kemungkinan tidak menemukannya di DOM Halaman.

Berikut adalah sumber yang diberikan halaman saat Anda memanggil RegisterStartupScriptmetode:

<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. Saat Anda menggunakan RegisterClientScriptBlock, skrip diberikan tepat setelah tag kondisi tampilan, tetapi sebelum elemen halaman mana pun. Karena ini adalah skrip langsung (bukan fungsi yang dapat dipanggil , itu akan segera dieksekusi oleh browser. Tetapi browser tidak menemukan label di DOM Halaman pada tahap ini dan karenanya Anda harus menerima "Objek tidak ditemukan" kesalahan.

Berikut adalah sumber yang diberikan halaman saat Anda memanggil RegisterClientScriptBlockmetode:

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

Oleh karena itu, untuk meringkas, Anda harus memanggil metode yang terakhir jika Anda bermaksud untuk membuat definisi fungsi. Anda kemudian dapat membuat panggilan ke fungsi itu menggunakan metode sebelumnya (atau menambahkan atribut sisi klien).

Edit setelah komentar:


Misalnya, fungsi berikut akan berfungsi:

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); 
  } 
} 
Cerebrus
sumber
1
Bisakah Anda menjelaskan lebih banyak tentang fungsi inline?
Xaisoft
2
Mengedit posting saya untuk menggambarkan dengan lebih baik terhadap contoh Anda.
Cerebrus
1
Saya sebenarnya tidak mendapatkan kesalahan, waktu diperbarui, tetapi warnanya tidak berubah. Bagaimana dengan bagian pertanyaan saya di mana saya bertanya apakah saya harus menggunakan ScriptManagerProxy jika saya sudah memiliki ScriptManager yang sudah didefinisikan di halaman master?
Xaisoft
1
Pengeditan selesai. Saya tidak yakin tentang kesalahan dengan ScriptManagerProxy. Saya pikir Anda harus mengevaluasi jika itu bukan pertanyaan yang terpisah. ;-)
Cerebrus
1
Bagus! Terima kasih sejauh ini Saya tidak mendapatkan kesalahan dengan ScriptManagerProxy. Saya hanya tahu bahwa Anda hanya dapat mendeklarasikan satu instance dari ScriptManager, jadi jika saya sudah memiliki ScriptManager yang didefinisikan di halaman master misalnya, saya akan berasumsi bahwa saya akan menggunakan ScriptManagerProxy sebagai gantinya.
Xaisoft
6

Berikut adalah contoh paling sederhana dari Komunitas ASP.NET, ini memberi saya pemahaman yang jelas tentang konsep ....

apa bedanya ini?

Untuk contohnya, berikut adalah cara untuk memfokuskan pada kotak teks pada halaman ketika halaman dimuat ke dalam browser — dengan Visual Basic menggunakan RegisterStartupScriptmetode:

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

Ini berfungsi dengan baik karena kotak teks pada halaman dihasilkan dan ditempatkan pada halaman pada saat browser turun ke bagian bawah halaman dan sampai ke sedikit JavaScript ini.

Tetapi, jika sebaliknya ditulis seperti ini (menggunakan RegisterClientScriptBlockmetode):

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

Fokus tidak akan sampai ke kontrol kotak teks dan kesalahan JavaScript akan dihasilkan pada halaman

Alasan untuk ini adalah bahwa browser akan menemukan JavaScript sebelum kotak teks ada di halaman. Oleh karena itu, JavaScript tidak akan dapat menemukan TextBox1.

pengguna c-tajam
sumber