我正在开发一个Windows 8 Metro应用程序,我发现即使是在他们的示例应用程序中(我没有更改过代码),当你在页面之间导航时,顶级的 "default.html" 会获取应用程序运行期间加载过的每个js和css文件。
这导致我的css在不同页面之间发生冲突,给我带来了很多麻烦。我是否漏掉了什么或者这是一个严重的错误?
这导致我的css在不同页面之间发生冲突,给我带来了很多麻烦。我是否漏掉了什么或者这是一个严重的错误?
不卸载JavaScript和CSS是一个有意为之的选择,而不是疏忽或失误。
首先,要明白页面控件完全是JavaScript构建的 - 浏览器引擎完全不知道它们的存在。浏览器只看到由脚本动态生成的DOM块。
Web平台不允许您卸载脚本文件 - 一旦它们加载到上下文中,它们将永久存在。
对于CSS,他们可以尝试删除标签,但这会带来很多麻烦。根据导航到页面的顺序不同,您可能会在同一应用程序中应用不同的样式。如果两个页面都引用相同的样式表怎么办?您添加两个相同的链接标记吗?那要删除哪一个呢?
这是一团乱麻。相反,WinJS保证脚本和样式表仅在第一次被引用时加载一次。因此,您可以使应用程序中的每个页面都引用“myStyles.css”,它只会被加载一次(并且只会有一个样式标记)。
那么如何防止出现您所见到的问题?首先要记住你正在构建一个应用程序,而不是将任意增长的新内容添加到网站。确定您的通用样式和类别。将共享的样式放在default.css中,并从default.html文件引用它。
对于各个页面,最简单的方法是为样式名称加上页面名称前缀。而不是:
<div class='intro'></div>
执行
<div class='page1-intro'></div>
如果您使用命名空间,就可以确保避免冲突。
如果您要通过ID引用页面元素,请不要这样做。在页面中使用ID会导致各种潜在的奇怪问题(如果同时呈现相同的页面控件会怎样?另外,ID要在页面加载到DOM后才存在,这意味着基于ID的data-win-options引用不起作用)。但如果您坚持要这么做,考虑使用页面前缀作为ID的命名空间。
基本上,设置临时命名空间可以避免冲突。这比手动删除链接标记要容易得多,并且会产生比执行完整导航更好的应用程序体验。
这可能是一个采用约定命名方法的好解决方案:
var currentPage = Application.navigator.pageControl.uri.replace("ms-appx://" + Windows.ApplicationModel.Package.current.id.name.toLowerCase(), "");
var currentCss = currentPage.replace(".html", ".css");
var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"];
WinJS.Utilities.query("link").forEach(function (linkElem) {
if (linkElem.href.toLowerCase().indexOf(currentCss) > -1) {
linkElem.disabled = false;
} else {
var ignore = false;
ignoreList.forEach(function (ignoreItem) {
if (linkElem.href.toLowerCase().indexOf(ignoreItem.toLowerCase()) > -1) {
ignore = true;
}});
if (!ignore) {
linkElem.disabled = true;
}
}
});
link
元素,并禁用不需要的元素来解决此问题。确保不要禁用MS CSS文件和项目中的default.css文件(假设您使用它来定义应用程序的通用样式)。WinJS.Pages.UI.render
方法加载时将定位和禁用不需要的link
元素。确保启用page2.css文件并保留简单忽略的文件列表。ready
处理程序函数中,但我倾向于在WinJS.Navigation事件处理程序中使用此技术,并依靠一致的文件命名获得所需结果)。<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>UnloadCSS</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- UnloadCSS references -->
<link href="/css/page2.css" rel="stylesheet" />
<script>
WinJS.UI.Pages.define("/page2.html", {
ready: function () {
var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"];
var myCSS = "/css/page2.css";
WinJS.Utilities.query("link").forEach(function (linkElem) {
if (linkElem.href.indexOf(myCSS) > -1) {
linkElem.disabled = false;
} else {
var ignore = false;
ignoreList.forEach(function (ignoreItem) {
if (linkElem.href.indexOf(ignoreItem) > -1) {
ignore = true;
}
});
if (!ignore) {
linkElem.disabled = true;
}
}
});
}
});
</script>
</head>
<body>
<button>Change </button>
</body>
</html>