2010-01-10 21 views
3

我正在努力嘗試一些我認爲應該成爲標準實踐的東西。我有一些使用一些JQuery插件的用戶控件。我真的不想鏈接到我的主masterpage上額外的CSS和JS文件,因爲這會在用戶第一次訪問該網站時給用戶帶來額外的負載(不過,它只會是一次),所以我只是把它們鏈接到用戶控件的頂部。然後我看着我的HTML源代碼,不太好!對於在頁面上重複多次的控件更糟糕。將代碼從用戶控件注入到masterpage/html頭中

所以我在想有沒有一種方法可以在用戶控件需要它們時將它們注入頁面的頭部。對於這個問題有沒有辦法做到JS的頁腳?

回答

8

要動態地註冊一個腳本(並確保所有重複的合併)在ASP.NET中,你可以撥打:

Page.ClientScript.RegisterClientScriptInclude(
    "mykey", "~/scripts/jquery-1.3.2.js"); 

和閱讀MSDN這種方法的全部細節。

要添加CSS動態,你可以做這樣的事情:

HtmlLink cssLink = new HtmlLink(); 
cssLink.Href = "path to CSS"; 
cssLink.Attributes["some attr1"] = "some value1"; 
cssLink.Attributes["some attr2"] = "some value2"; 
Page.Header.Controls.Add(cssLink); 

注入CSS的這個例子不會合並重復條目。爲避免重複,您必須自行跟蹤重複項。一個可以存儲你已經註冊的腳本列表的地方是在HttpContext.Items中。在那裏保存一個HashSet,它保存了所有註冊腳本的列表,這樣你就不會註冊兩次相同的CSS文件(這通常是無害的,但是可以避免的)。

+0

這種方法是合理的,只是可以添加同一CSS文件的多個實例。例如,如果同一控件在同一頁面上存在多次。 – RickNZ 2010-01-11 06:09:48

+0

瑞克 - 非常好的一點。我編輯了我的答案,包括一些關於消除重複的註釋。 – Eilon 2010-01-11 17:46:21

+0

喜歡關於HttpContext.Items的代碼片段。在閱讀您的文章之前從未注意到這一點。感謝分享Eilon! – RichardB 2012-04-24 20:10:21

0

我假設你使用Asp.NET。

嘗試把一個內容佔位符在母版的...

<head> 
<asp:ContentPlaceHolder ID="AdditionalPageHeader" /> 
</head> 

如果你在一個aspx文件,或者你只需​​要定義一個內容控件的ASCX工作...

<asp:Content ContentPlaceHolderID="AdditionalPageHeader" /> 

如果你正在處理服務器控件的代碼隱藏唯一的類型,可以能獲得一個指向內容的佔位符:

this.Page.Master.FindControl("AdditionalPageHeader") 

...並以編程方式操作它的內容。

+1

有趣的解決方案。部分問題只有一個問題:您無法在用戶控件中定義內容控件。它們只能用於ASPX內容頁面。 – Eilon 2010-01-10 21:34:28

+0

我的第一個想法是將其添加到頭部,但是Eilon指出我無法通過聲明方式從UserControl訪問它。 – Jon 2010-01-10 22:15:57

0

要添加樣式表或JavaScript(在線與否)動態我寫了這三個功能:

Public Function addScript(ByVal path2js As String) As System.Web.UI.Control 
    Dim si As New HtmlGenericControl 
    si.TagName = "script" 
    si.Attributes.Add("type", "text/javascript") 
    si.Attributes.Add("src", path2js) 
    Return si 
    End Function 
    Public Function addScript_inline(ByVal js As String) As System.Web.UI.Control 
    Dim si As New HtmlGenericControl 
    si.TagName = "script" 
    si.Attributes.Add("type", "text/javascript") 
    si.InnerHtml = js 
    Return si 
    End Function 
    Public Function addStyle(ByVal path2css As String) As System.Web.UI.Control 
    Dim css As New HtmlLink 
    css.Href = path2css 
    css.Attributes.Add("rel", "stylesheet") 
    css.Attributes.Add("type", "text/css") 
    css.Attributes.Add("media", "all") 
    Return css 
    End Function 

我叫他們在Page_Load中對我的母版,就像這樣:

Me.Page.Header.Controls.Add(modGlobal.addScript("script/json/json2.js")) 

Me.Page.Header.Controls.Add(modGlobal.addStyle("style/flexigrid/flexigrid.css")) 

Regards

1

您可以使用ClientScript.RegisterClientScriptInclude()作爲JavaScript。

對於CSS,一個技巧是將它們包含在您的母版頁中,但是與Visible="false"一樣,以便它們在默認情況下不會被渲染到標記中。

然後,在您的用戶控件中,從早期事件(例如OnLoad())中的Items集合中設置一個標誌。例如,this.Context.Items["mycss"] = true;

最後,在您的母版頁中,從後面的事件(例如OnPreRender())中檢查是否設置了這些標誌。如果是,則將Visible屬性設置爲true以獲取相應的CSS。

這也允許您使用不使用CSS的母版頁控件,因爲Items條目可以簡單地被忽略。如果您有許多需要相同行爲的母版頁,則可以將此代碼放入基類或使用嵌套母版頁。

1

我遵循類似的方法,但我直接在用戶控件中使用CSS,所以我不必導入CSS文件。以下是完全從樣本用戶控件代碼:

<style id="style1" type="text/css" visible="false" runat="server"> 
    td { font-family: Tahoma; font-size: 8pt; } 
</style> 

在後臺代碼:

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 

    HtmlGenericControl style = new HtmlGenericControl("style"); 
    style.Attributes.Add("type", "text/css"); 
    style.InnerHtml = style1.InnerHtml; 
    Page.Header.Controls.Add(style); 
} 

你會發現CSS在head標籤渲染,而不是身體標籤內。