在.NET中以编程方式向用户控件添加Javascript文件

17

如何以编程方式将Javascript文件添加到用户控件中?

我希望用户控件是一个完整的包 - 也就是说,当我可以在控件本身内部完成时,我不想在使用它的页面上添加与用户控件相关的javascript。

由于用户控件中不存在Page对象,因此您应该如何实现它?

8个回答

26

在control.ascx.cs文件的Page_Load方法中:

LiteralControl jsResource = new LiteralControl();
jsResource.Text = "<script type=\"text/javascript\" src=\"js/mini-template-control.js\"></script>";
Page.Header.Controls.Add(jsResource);

HtmlLink stylesLink = new HtmlLink();
stylesLink.Attributes["rel"] = "stylesheet";
stylesLink.Attributes["type"] = "text/css";
stylesLink.Href = "css/mini-template-control.css";
Page.Header.Controls.Add(stylesLink);

这将把 CSS 和 JavaScript 加载到主页面的 head 标签中,请确保 head 标签具有 runat="server" 属性。


1
Gnomixa,非常好的解决方案。+1 - Tangiest
这太酷了!我过去只是把所有的脚本放在ascx设计页面中。但是,如果JavaScript文件已经添加到页面头部(可能是由不同的ascx控件添加),你该如何处理呢? - ak3nat0n
@zaladane,我从未遇到过这种情况,因为我完全控制了加载的内容和时间。我会编写一个简单的函数来循环检查添加的内容,并确保不会重复添加。但是,我认为您可以将同一JS文件多次添加到同一页中,最终不应该影响任何内容。尝试一下并确认。 - sarsnake
1
如果您有多个控件的实例,这是不好的。请参见下面的baretta帖子。 - Martin Murphy
多个实例上也一样。Baretta的答案没有解决CSS包含问题,我通过使用带有ID的HtmlLink来解决了这个问题。 - Oyvind

9
您可以使用ClientScriptManager注册客户端脚本包括。页面可通过Control.Page属性访问。
Page.ClientScript.RegisterClientScriptInclude (
  typeof ( MyControl ), "includeme.js", "js/includeme.js"  );

编辑:抱歉,对于完整的“完整包”,可以使用脚本作为嵌入式资源,并通过WebResource.axd处理程序获取动态URL。 如果这不被认为是完全的,则可以将其放在App_LocalResources中,但它永远不会只是一个文件, 除非代码和脚本是内联的。


用户明确提到他希望他的整个控件是一个“完整的包”。这个解决方案假设该控件是与一个JavaScript文件一起添加的,这不是一个完整的包。 - David Morton
被接受的答案没有嵌入JavaScript文件,是吗? - Greg

6
与gnomixa的回答相同,只是更加简洁:

与gnomixa的回答相同,只是更加简洁:

HtmlGenericControl js = new HtmlGenericControl("script");
js.Attributes["type"] = "text/javascript";
js.Attributes["src"] = "jscript/formfunctions.js";
Page.Header.Controls.Add(js);

来自http://www.aspdotnetfaq.com/Faq/How-to-Programmatically-add-JavaScript-File-to-Asp-Net-page.aspx的内容:

如何以编程方式向Asp.Net页面添加JavaScript文件?

在许多情况下,我们需要动态地向Asp.Net页面添加JavaScript文件。这可以通过使用Page类的RegisterClientScriptInclude方法来实现。以下是示例代码:

string jsname = "test.js";
string jspath = "/Scripts/test.js";
Page.ClientScript.RegisterClientScriptInclude(jsname, jspath);

在上面的示例中,我们将test.js文件添加到了/Scripts文件夹中,并使用RegisterClientScriptInclude方法将其添加到页面中。


4
在我的网站中,我将所有必需的脚本和样式放置在占位符中。
<asp:placeHolder runat="Server" ID="phHead">
    <script src="/header/widget/script.js" type="text/javascript"></script>
    <link href="/header/widget/style.css" rel="stylesheet" type="text/css" />
</asp:placeHolder>

并且

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Page.Header.Controls.Add(phHead)
End Sub

2

我正在使用网站项目而不是Web应用程序,因此我没有AssemblyInfo.cs文件。 我宁愿继续使用这个模型,因为我比Web应用程序更喜欢它。 - sarsnake
网站项目是微软的一个巨大错误。它非常缓慢,因为它为所有东西创建程序集!但好的一面是现在你可以将用户控件用作服务器控件。 - azamsharp

0

我发现这是一种更优雅的修复JavaScript链接的方法。
在您的.ascx文件中,以以下方式链接到您的脚本文件:

<script src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.1.min.js") %>' type="text/javascript"></script>
<script src='<%= ResolveClientUrl("~/Scripts/jquery.maskedinput-1.3.min.js") %>' type="text/javascript"></script>

这样,无论您将用户控件添加到哪个子文件夹/页面,脚本链接都将始终被正确解析。


0

通常我会在控件的 HTML 渲染时执行,具体取决于是库注入还是实例注入,我使用 Items 集合来指定当前请求期间是否已经为这种类型的控件生成了代码,并使用唯一标识符。

类似于以下内容:

    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(writer);

        //Check if the Object Script has already been rendered during this request.
        if (!Context.Items.Contains("xxx"))
        {
            //Specify that the Object Script has been rendered during this request.
            Context.Items.Add("xxx", string.Empty);
            //Write the script to the page via the control
            writer.Write([libraryinjection]);
        }
        //Write the script that instantiates a new instance for this control
        writer.Write([instanceinjection]);
    }

它可以在ascx.cs级别完成,或者如果控件是纯代码,则可以在库中的代码级别完成。 - Quintin Robinson
哦,好的,[libraryinjection]是什么?不好意思,我以前从没见过这个:) 还有你说的xxx是什么意思?是说类似于myscript.js这样的东西吗? - sarsnake
是的,那只是一个占位符。如果您想将脚本打包为资源或类似的东西,那么它将是其字符串表示形式,无论是 "<script src='myscripthandler.ashx?f=myscript.js'></script>" 还是整个脚本本身。 - Quintin Robinson

0
如果您在 .CS 文件中具有实际 JavaScript 的文本,可以调用 Page.ClientScript.RegisterClientScriptBlock。
以下假定“GetScript()”返回您要添加到呈现控件的实际 JavaScript。
Page.ClientScript.RegisterClientScriptBlock(GetType(), "controlScriptName", GetScript());

我想把JavaScript放在独立的文件中。是否可以通过编程将JS文件添加到用户控件中?如果不行,我将使用Dennis的解决方案。 - sarsnake
你可以使用类似 File.ReadAllText 的方法将文件读入字符串,然后使用该文本注册客户端脚本块,但如果您想把它放在自己的文件中,我建议使用 Dennis 的解决方案。 - David Morton
哇,没想到给用户控件添加JS文件会这么麻烦。顺便说一下,我现在在.ascx文件中加了<script></script>代码,它可以运行,但由于用户控件里没有<head>标签,所以看起来有点靠不住,但我想我还是要坚持这种方法。 - sarsnake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接