最近在开发产品时发现一个问题,我的项目是拥有几个master模板的,但是各模板都有一些相同的样式css链接及js链接,刚开始的处理方式是在各模板上分别加入这些共同的样式及js链接,本来已觉得这么样有些不符使用模板的原则,但因为只有几个模板,所以勉强可以接受。但在开发时发现一个问题,当master模板放在比引用页面更深的目录时出现了问题,经过折腾测试发现了原因:master模板对于不正确的css外链接会自动修改它的地址的,却改的不对,对script链接却不变。因为我用的是相对路径,当master模板加载css外链接时它是以模板自已的目录为相对目录的,这就出现了一个问题,因为模板与页面不在同一个目录下,所以它自动修改后的路径对于网页来说是不正确的,改成以master为相对目录的路径,经过模板自动修改后的生成的网页上的css外链接就是正确的了。如网页的路径是web/default.aspx,模板的路径是web/master/main.master,引用的样式路径web/skin/genaral.css,那么放在default.aspx上的链接是./skin/genaral.css,但是如果这链接放在main.master上,它的路么就要写成../skin/genaral.css生成网页后模板会把它改成./skin/genaral.css。说到这里你可能会觉得没有问题,能正确显示就好了,但是如果还有js引用文件也放在web/skin目录下,你会发现它放在main.master上的链接要写成./skin/genaral.js生成的网页才能引用到正确的链接,因为模板不会修改script的链接地址。这样我觉的是有点奇怪的,因放同一目录下的js、css在main.master上的引用链接地址要分别写成./skin/genaral.css和../skin/genaral.js。当然,如果你把写成与根目录为相对目录的链接且用上~符号就没有这个问题了。
对于有不同目录的引用页面来说,以模板为相对目录确实是需要这样才能通用。你可能会想用一个模板做唯一的共享数据模板,然后其他模板再套那个模板,不过这种方式我觉的有点简单粗暴,且不知道性能会有多大影响,这不符合我的设计美学。我还是想了一方法来解决我的项目的问题。因为我的项目还有一个需求:统一主题样式文件管理。把css、js、skin统一放到App_Themes上管理。解决办法其实很简单,也比较巧妙(呵呵,自我赞一下),就是自定义一个控件用于放css、js链接。我的控件是这样子的:
<EasyWeb:ThemeStyleSheet runat="server"> <StyleText> 这里放需要引用的代码 </StyleText> </EasyWeb:ThemeStyleSheet>
只要把这个控件加上需要使用的各css、js 放到App_Themes下的.skin文件上:
skin主题文件上:
<EasyWeb:ThemeStyleSheet runat="server"> <StyleText> <link href="../themes/css/ui-lightness/jquery-ui-1.8.18.custom.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../themes/js/jquery-1.7.1.min.js"></script> <script type="text/javascript" src="../themes/js/jquery-ui-1.8.18.custom.min.js"></script> <link href="./skinCss/general.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="./js/general.js"></script> </StyleText> </EasyWeb:ThemeStyleSheet>
直接写css代码或js代码也是可以的。
及在需要引用的模版上添加这个控件:
master模板上:
<head id="Head1" runat="server"> <title></title> <meta http-equiv="expires" content="1900/01/01"/> <base target="_self"/> <EasyWeb:ThemeStyleSheet ID="ThemeStyleSheet1" runat="server"></EasyWeb:ThemeStyleSheet> </head>
是不是很简单很方便呢?其实这个控件没什么特别的,你用PlaceHolder容器控件也可以,不过用了这个控件做这个功能后,你就不能再其他地方使用了,所以自定义一个最好了。
关于自定义控件的方法,如果你会可以忽略,如果不会可以网上找一找一大把,这里就不教了。如果你不知道App_Themes,那么你先学会再看这篇文章吧。
最后说一下另一种处理方法,有些人可能会在站点事件BeginRequest上或Response.Filter上对生成的网页代码添加,这种方式好不好呢?我是觉得不好,重要的是在管理及使用上不那么方便。
如果你的项目自定义了page接口,做一个架构管理样式,那么当然没什么好说的了。