WebForms:MasterPages 中的动态(或绝对)脚本标记
问题
在使用母版页时,我遇到的一个常见问题是母版中的脚本标记与使用页面相关。
例如,如果您的消费页面位于应用程序的根目录中,您的 JavaScript 可能会起作用,但是当您将另一个页面放入子文件夹中时,相对路径会中断并且找不到 JavaScript。 在这种情况下,没有办法使用我所知道的绝对路径。
最后一次,我决定真正解决这个问题并找到一个好的解决方案。
建议的解决方案
我尝试了一种围绕在 Page_Load 中调用 ClientScriptManager.RegisterClientScriptIninclude 的策略,但这似乎没有呈现任何内容(当然,我对相关管道的理解不完整)。
我尝试了另一个看起来像这样的:
<script language="javascript" src='<%= ResolveClientUrl("~/js/ddnmenu.js") %>' type="text/javascript"></script>
...但这引发了一个异常:无法修改 Controls 集合,因为该控件包含代码块。
工作(但有些丑陋)代码
所以,我最终使用的是 Head 中的文字控件,我在其中渲染适当的 Html:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.SetupLiteralScriptsTag()
End Sub
Private Sub SetupLiteralScriptsTag()
'Build the script tags to import our JavaScript
Dim Builder As New StringBuilder
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery-1.3.2.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery.corners.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/bg.pos.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/moonstone.js")))
Me.LiteralScriptTags.Text = Builder.ToString
End Sub
这可行,但我对此并不着火,因为它对于一个极其常见的问题来说,似乎有点太多的解决方法。 有没有更好的办法?
Problem
When working with MasterPages, a common irritation I run into is that script tags in the master are relative to the consuming page.
So for instance, your JavaScript might work if your consuming page is in the root of your app, but when you put another page in a subfolder, the relative path breaks and the JavaScript is not found. And there isn't a way to use absolute paths that I'm aware of in this case.
This last time, I decided to really attack this and find a good solution.
Proposed Solutions
I tried one strategy that revolved around calling ClientScriptManager.RegisterClientScriptInclude in Page_Load, but that didn't seem to render anything (granted, my understanding of the related plumbing is incomplete).
I tried another one that looked something like this:
<script language="javascript" src='<%= ResolveClientUrl("~/js/ddnmenu.js") %>' type="text/javascript"></script>
...But that throws an exception: The Controls collection cannot be modified because the control contains code blocks.
Working (but somewhat fugly) Code
So, what I ended up going with is a Literal control in the Head where I render the appropriate Html:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.SetupLiteralScriptsTag()
End Sub
Private Sub SetupLiteralScriptsTag()
'Build the script tags to import our JavaScript
Dim Builder As New StringBuilder
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery-1.3.2.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery.corners.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/bg.pos.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/moonstone.js")))
Me.LiteralScriptTags.Text = Builder.ToString
End Sub
This works, but I'm not on fire about it since it seems like a bit too much of a workaround for what must be an extremely common problem. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以将脚本管理器添加到母版页并通过该方法包含 javascript 文件:
该方法的另一个优点是您可以将 ScriptManagerProxy 控件添加到内容页(和用户控件)以包含任何其他脚本。
ASP:ScriptManager 的一些第三方替代品(例如来自 telerik 的 RadControls 套件或来自 Ajax 控制工具包)提供更多功能,例如将所有包含的 java 脚本文件合并到一个文件中(从而减少所需的 HTTP 请求数量)加载页面)。
编辑:
使用 ScriptManager 还有一些其他优点,例如,您可以将脚本的调试或发布版本或文化相关的脚本等发送到浏览器。请查看 MSDN 中的此页面 了解概述。
You could add a scriptmanager to the master page and include the javascript files via that:
Another advantage of that approach is that you can then add a ScriptManagerProxy control to your content pages (and user controls) to include any additional scripts.
Some third-party replacements for ASP:ScriptManager (e.g. from telerik's RadControls suite or from the Ajax control toolkit) offer even more features, such as merging all included java script files into one file (thus reducing the number of required HTTP requests to load a page).
Edit:
using a ScriptManager has some other advantages e.g. you can send debug or release versions of your scripts to the browser, or culture-dependent scripts, etc. etc. Have a look at this page in MSDN for an overview.
我到处都使用应用程序相对语法。 它确实有一个缺点,如果您更改应用程序名称/路径,那么您需要做大量工作来更新所有 URL。
<脚本语言=“javascript”src=“/MyAppName/Includes/MyJavascriptFile.js”>
或者如果您正在使用根应用程序,则:
I use app relative syntax everywhere. It does have the drawback that if you change app name/path, then you have alot of work to do updating all of your URL's.
<script language="javascript" src="/MyAppName/Includes/MyJavascriptFile.js">
or if you were working on the root app, then:
<script language="javascript" src="/Includes/MyJavascriptFile.js">
我使用
Page.resolveUrl("~/somefile.js");
效果很好
I use
Page.resolveUrl("~/somefile.js");
works like a champ
您可以始终从根目录引用您的脚本。 IE:
应用程序中的任何页面都会正确获取 javascript。
另外,由于您正在使用 ASP.NET,因此您可以使用“~”字符来提供基于应用程序的相对路径。 有关详细信息,请参阅 Rick Strahl 有关 ASP.NET 路径的文章。
You could reference your script always from the root. IE:
Any page in your app would then get the javascript properly.
Also, since you are working with ASP.NET you could make use of the "~" character for providing application based relative paths. See Rick Strahl's article on ASP.NET paths for more info.
该错误听起来很熟悉。 此页面在我摸索着浏览此页面时提供了帮助
That error sounds familiar. This page helped when I fumbled my way through this one