2012年7月12日 星期四

ASP.NET上使用JavaScript的方法 (二)

繼上一篇文章ASP.NET上使用JavaScript的方法 (一)
談到了在HTML原始碼上面寫進JavaScript的三種方式
是比較傳統的作法

這篇文章才算是真正的進入ASP.NET的範疇
主要是談怎麼在Server端寫Code 程式碼的時候也一併寫JavaScript

寫在前面:這邊我還是延用上一專題ASP.NET上使用JavaScript的方法 (一)的案例「限制級網頁」來探討如何使用JavaScript,Script的內容是一樣的,如下:

    <script type="text/javascript">
            if (confirm('以下內容為限制級,如果你已年滿18歲請按確定繼續觀看,否則請按取消 '))
        { document.write('你按了確定, 這些畫面很暴力、很情色吧…') }
        else {document.getElementById('Panel1').style.visibility = 'hidden'}
    </script>

和上篇文章不同的地方,是我修改了一下畫面的設計,在圖片的部分,我這次不用HTML來維護圖片的長度和寬度,改用CSS設計的方式…把程式碼區塊弄得更複雜一些。HTML原始碼如下:

<head runat="server">
    <title></title>
    <style type="text/css">
        .style1
        {
            width: 100px;
            height: 80px;
        }
        .style2
        {
            width: 100px;
            height: 80px;
        }
        .style3
        {
            width: 100px;
            height: 80px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>    
        <img alt="溫馨圖片,普通級" class="style1" src="Images/test0.jpg" /><br />
        <asp:Panel ID="Panel1" runat="server" style="margin-bottom: 0px">
            <img alt="暴力圖片,限制級" class="style2" src="Images/test1.jpg" />
            <img alt="情色圖片,限制級" class="style3" src="Images/test2.jpg" />
        </asp:Panel>    
    </div>
    </form>
</body>
</html>

用CSS的結果和直接用HTML的Image設定是一樣的,這麼是多此一舉,只是想把HTML弄得複雜一點,JavaScript會看得比較清楚,所以就先用上去吧。
image

後面就來介紹其他的幾種使用方法。


方法1、Response.Write("JavaScript的字串")


反正程式碼就是一堆字串連接
所以如果非得要在程式碼的地方寫入
用字串連接的藝術大師…Response.Write
底下我們把JavaScript寫在Page_Load事件裡

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Response.Write("<script type='text/javascript'> if (confirm('以下內容為限制級,如果你已年滿18歲請按確定繼續觀看,否則請按取消 ')) { document.write('你按了確定, 這些畫面很暴力、很情色吧…') } else {document.getElementById('Panel1').style.visibility = 'hidden'} </script>")
    End Sub

有沒有發現上面的JavaScript好長一句…這樣子寫的話,後期要修改的話非常的吃力
所以可以修改一下寫法,如下

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim js As String = ""
        js &= "<script type='text/javascript'>"
        js &= "if (confirm('以下內容為限制級,如果你已年滿18歲請按確定繼續觀看,否則請按取消'))"
        js &= "{ document.write('你按了確定, 這些畫面很暴力、很情色吧…') }"
        js &= "else {document.getElementById('Panel1').style.visibility = 'hidden'}"
        js &= "</script>"
        Response.Write(js)
    End Sub

這個改寫對程式執行來說是沒差的,就好像習慣上,JavaScript 程式敘述結尾會加上分號(;),表示一個完整敘述的結束。其實分號並不是必要的,只要每一句程式敘述皆不同行,是可以省略分號的,加分號的目的不過為了程式的完整性,以及日後維護程式方便。

甚至對於更長的JavaScript,我們還可以用載入外部 JavaScript 檔案 *.js的方式 來完成案例。寫法入下

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Response.Write("<script src='JScript.js' type='text/javascript'></script>")
    End Sub


那麼程式執行起來ok嗎,請看deom:http://dnowba.somee.com/aspnet37_8.aspx
當按下「取消」時,出現了很熟悉的錯誤「錯誤:此處需要物件」
錯誤真是陪伴我們人生的好朋友啊,一看到我們就知道,是JavaScript 在HTML上「位置」的問題…檢查一下browser端的HTML碼
image

JavaScript跑出整個網頁標記的最外面了…當然抓不到page後面才生成的控件
這是response的特性,我之前有一篇文章關於Response 和Request可以參考。所以我們要修正這個錯誤,就要想一個在code寫JavaScript,但又兼顧位置的方法。


方法2、用註冊的方式加到HTML的固定位置


可以兼顧位置的寫法,就是使用RegisterClientScriptBlock 與 RegisterStartupScript、RegisterClientScriptInclude三個方法。以下分項說明:

◎RegisterClientScriptBlock 的範例:把JavaScript註冊到<body>區塊 最頂端

        If (Not IsClientScriptBlockRegistered("clientScript")) Then
            RegisterStartupScript("clientScript", "<script src='JScript.js' type='text/javascript'></script>")
        End If

上面程式碼,行2是在確定網頁是不是已經有註冊過名為「clientScript」的JavaScript了,如果沒有的話,就進行註冊,可以避免衝突…使用後我們看看一下在browser端的HTML碼,JavaScript的位置
image
這個位置也太尷尬了吧,直接在<body>、<form>下接著寫JavaScript,其他的網頁元素像<panel>都還沒讀取完,這種放法和放在<html>區塊有差別嗎?我想這個範例的結果怎樣可想而知,demo:http://dnowba.somee.com/aspnet37_9.aspx

◎RegisterClientScriptInclude的範例:把JavaScript註冊到<head>裡

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If (Not IsClientScriptBlockRegistered("clientScript")) Then
            Page.ClientScript.RegisterClientScriptInclude("js", "JScript.js")
        End If
    End Sub

這個Method裡,RegisterClientScriptInclude是用引用js檔案的方式,其後的參數是
RegisterClientScriptInclude (“識別名稱”, “檔案位置+檔案名稱” ),引用的方式和前一例有異趣同工之妙,所以方法真的很多種。
demohttp://dnowba.somee.com/aspnet37_12.aspx裡,可以檢視JavaScript是在<head>裡

◎RegisterStartupScript 的範例:把JavaScript註冊到<body>區塊最末端

使用這個Method,JavaScript會被註冊到<body>區塊的最末端。結果我想也不用多提了。這邊就加減介紹,補充一下字串連接的另一種方式 (微軟建議的)

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If (Not IsClientScriptBlockRegistered("clientScript")) Then
            Dim js As New StringBuilder()
            js.Append("<script type='text/javascript'>")
            js.Append("if (confirm('以下內容為限制級,如果你已年滿18歲請按確定繼續觀看,否則請按取消'))")
            js.Append("{ document.write('你按了確定, 這些畫面很暴力、很情色吧…') }")
            js.Append("else {document.getElementById('Panel1').style.visibility = 'hidden'}")
            js.Append("</script>")
            RegisterStartupScript("clientScript", js.ToString())
        End If
    End Sub

以下是範例:http://dnowba.somee.com/aspnet37_10.aspx

方法2 裡的RegisterClientScriptBlock 與 RegisterStartupScript 的方法,不管哪一種,其實註冊JavaScript的位置都不能達成我們的需求。最好還是把JavaScript放在<panel>控制項產生後,image之前。我們試試用最後一個方法來看看是否能解決問題。


方法3、把JavaScript 加在控制項上

這個方法是在控制項後調用 Attributes.Add("javascript事件","javascript語句")
程式碼如下,行6就是把Image控制項加上一個JavaScript事件「onload」,當圖片加載完畢後,就引發js這串程式。

所以為了要加載到控制項上,我把原來的Image改成「run at server」的方式以便控制
(在工具箱裡,「HTML索引標籤」的Image 和「標準索引標籤」的Image是不一樣的,最大的差別就是標記中,標準索引標籤的Image多了一個「run at server」,而這個Image控制項才能在code處被直接呼叫。

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim js As New StringBuilder()
        js.Append("if (confirm('以下內容為限制級,如果你已年滿18歲請按確定繼續觀看,否則請按取消'))")
        js.Append("{ document.write('你按了確定, 這些畫面很暴力、很情色吧…') }")
        js.Append("else {document.getElementById('Panel1').style.visibility = 'hidden'}")
        Me.Image1.Attributes.Add("onload", js.ToString)
    End Sub

deom 請看:http://dnowba.somee.com/aspnet37_11.aspx
在進入網頁,跳出confirm視窗,按下確定時就會出錯了。
在這個案例上使用方法3純綷是亂搞,只是想方法,看能不能在透過code建立JavaScript,又可以把JavaScript放到自已想放的位置。不過從上面我們也可以知道,JavaScript如果附加在控制項上,是要有一個JavaScript 事件來引發程式碼的。以下也提供一下「JavaScript事件參考」

事件 解釋
onabort 圖像加載被中斷
onblur 元素失去焦點
onchange 用戶改變域的內容
onclick 鼠標點擊某個對象
ondblclick 鼠標雙擊某個對象
onerror 當加載文檔或圖像時發生某個錯誤
onfocus 元素獲得焦點
onkeydown 某個鍵盤的鍵被按下
onkeypress 某個鍵盤的鍵被按下或按住
onkeyup 某個鍵盤的鍵被鬆開
onload 某個頁面或圖像被完成加載
onmousedown 某個鼠標按鍵被按下
onmousemove 鼠標被移動
onmouseout 鼠標從某元素移開
onmouseover 鼠標被移到某元素之上
onmouseup 某個鼠標按鍵被鬆開
onreset 重置按鈕被點擊
onresize 窗口或框架被調整尺寸
onselect 文本被選定
onsubmit 提交按鈕被點擊
onunload 用戶退出頁面

有了以上的想法,我又想到試試建立一個空的控制項HtmlGenericControl
然後一樣用Attributes.Add來寫,其實真正的的Attributes寫法應該是
控制項.Attributes.Add("屬性", "屬性的值")
所以下面的方法也提供給大家作參考 (當然以這個案例來說,用這個方式的結果還是不大好),大家可以demo試試http://dnowba.somee.com/aspnet37_13.aspx

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim objjquery As New HtmlGenericControl("script")
        objjquery.Attributes.Add("language", "javascript")
        objjquery.Attributes.Add("src", "JScript.js")
        Me.Panel1.Controls.Add(objjquery)
    End Sub


後記

這篇文章提到的方法
雖然物件Method是由Framework所提供
但是我自已覺得並不一定要強調開發ASP.NET就一定要用這種方式殖入JavaScript
有時候和傳統的方法來比較
反而傳統作法比較容易維護
端看使用的目的和時機
例如動態生成的控制項,就適合一併在code時加入JavaScript
如果是hard code,那麼就寫死在HTML裡也不為過

沒有留言:

張貼留言

Related Posts Plugin for WordPress, Blogger...
// Dnow Function