我正在开发一个 Windows 8 Metro 应用程序,我发现(即使在我没有触及代码的他们的示例应用程序中)当您在页面之间导航时,顶级“default.html”获取每个 js 和在应用程序运行期间加载的 css 文件。
这让我很头疼,因为我的 css 在不同的页面之间发生冲突。我错过了什么还是这是严重的错误?
我正在开发一个 Windows 8 Metro 应用程序,我发现(即使在我没有触及代码的他们的示例应用程序中)当您在页面之间导航时,顶级“default.html”获取每个 js 和在应用程序运行期间加载的 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 引用的选项不起作用)。但是,如果您再次坚持,请考虑在页面前加上 id 前缀。
基本上,设置临时命名空间以防止发生冲突。这比手动撕掉链接标签要容易得多,并且会比进行完整导航带来更好的应用体验。
它不是错误,它是 WinJS 模板使用的默认应用程序模式的一部分。默认的 WinJS 模板使用单页模型,这意味着所有内容都使用 PageNavigatorControl 加载到 default.html 中。因此,内存中始终只有一个 DOM。如果您在常规浏览器中遵循类似的模式,您会看到相同的行为。
如果需要,您可以使用多个页面和传统的 href 链接来使用更传统的导航。这不是推荐的方法,但如果您尝试引入使用该模型构建的现有 Web 资产,它可以使事情变得更容易。
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>
这可能是使用约定名称方法的一个很好的解决方案:
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;
}
}
});