我正在开发一个Windows 8 Metro应用程序,我发现(即使在我没有触及代码的示例应用程序中),当您在页面之间导航时,顶级“default.html”获取每个在应用程序运行期间加载的单个js和css文件。
由于我的css在差异页面之间发生碰撞,这引起了很多麻烦。我错过了什么或这是严重的错误吗?
答案 0 :(得分:13)
不卸载JavaScript和CSS是一个慎重的选择,而不是意外或疏忽。
首先,了解页面控件纯粹是一种JavaScript构造 - 浏览器引擎完全不了解它们。浏览器只看到一块由脚本动态生成的DOM。
Web平台不允许您卸载脚本文件 - 一旦它们被加载到上下文中,它们就永远存在。
使用CSS,他们可以尝试删除标签,但它会打开一堆蠕虫。根据导航到的订单页面,您最终可能会在同一个应用程序中应用不同的样式。如果两个页面引用相同的样式表怎么办?你是否两次添加相同的链接标签?你删除哪一个?
这是一团糟。相反,WinJS保证脚本和样式表只会被引用一次,第一次被引用。因此,您可以将应用中的每个页面都引用为“myStyles.css”,并且只会加载一次(并且只会有一个样式标记)。
那么你如何防止你所看到的问题呢?首先,请记住您正在构建一个应用程序,而不是一个随意增加新内容的网站。决定你的一般风格和课程。将共享样式放在default.css中,并从default.html文件中引用它。
对于单个页面,最简单的方法是在样式前加上页面名称。而不是:
<div class='intro'></div>
DO
<div class='page1-intro'></div>
然后你可以保证避免碰撞。
如果您按ID引用页面元素,请不要这样做。在页面中使用ID会导致各种各样的潜在怪异(如果您同时渲染相同的页面控件两次会怎么样?此外,在页面加载到DOM之后ID才会存在,这意味着数据赢 - ID的选项引用不起作用)。但是,如果你再次坚持,请考虑使用页面为id添加前缀。
基本上,设置临时命名空间以防止碰撞。这比手动删除链接标记要容易得多,并且会比完整导航带来更好的应用体验。
答案 1 :(得分:3)
它不是一个错误,它是WinJS tempaltes使用的默认应用程序模式的一部分。默认的WinJS模板使用单页模型,这意味着使用PageNavigatorControl将所有内容加载到default.html中。因此,内存中始终存在单个DOM。如果您在常规浏览器中遵循类似的模式,则会看到相同的行为。
如果需要,您可以使用更多传统导航,使用多个页面和传统的href链接。这不是推荐的方法,但如果您尝试使用该模型构建现有的Web资产,则可以使事情变得更容易。
答案 2 :(得分:0)
您可以通过查询文档以查找导入样式的link
元素并禁用您不想要的样式来解决此问题。您需要确保不要禁用项目中的MS CSS文件和default.css文件,假设您使用它来定义应用程序的常见样式。
以下示例说明如何执行此操作。这是一个名为page2.html的文件,当由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>
答案 3 :(得分:0)
这可能是一个很好的解决方案,具有约定名称aproach:
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;
}
}
});