Windows 8 WinJS未卸载js/css

Windows 8 WinJS未卸载js/css,windows-8,microsoft-metro,winjs,Windows 8,Microsoft Metro,Winjs,我正在开发一个Windows8Metro应用程序,我发现(即使在它们的示例应用程序中,我没有涉及代码),当您在页面之间导航时,顶级的“default.html”会获取应用程序运行期间加载的每个js和css文件 这让我很头疼,因为我的css在不同的页面之间发生冲突。我是遗漏了什么还是这是一个严重的错误?这不是一个错误,它是WinJS tempaltes使用的默认应用程序模式的一部分。默认的WinJS模板使用单页模型,这意味着所有内容都使用PageNavigatorControl加载到default

我正在开发一个Windows8Metro应用程序,我发现(即使在它们的示例应用程序中,我没有涉及代码),当您在页面之间导航时,顶级的“default.html”会获取应用程序运行期间加载的每个js和css文件


这让我很头疼,因为我的css在不同的页面之间发生冲突。我是遗漏了什么还是这是一个严重的错误?

这不是一个错误,它是WinJS tempaltes使用的默认应用程序模式的一部分。默认的WinJS模板使用单页模型,这意味着所有内容都使用PageNavigatorControl加载到default.html中。因此,内存中始终只有一个DOM。如果在常规浏览器中遵循类似的模式,则会看到相同的行为


如果您愿意,您可以使用更传统的导航,使用多个页面和传统的href链接。这不是推荐的方法,但如果您尝试使用该模型构建现有的web资产,则可以使事情变得更简单

您可以通过在文档中查询导入样式的
链接
元素并禁用不需要的元素来解决此问题。您需要确保不禁用项目中的MS CSS文件和default.CSS文件,假设您使用它来定义应用程序的常用样式

下面是一个示例,它向您展示了如何做到这一点。这是一个名为page2.html的文件,当由
WinJS.Pages.UI.render
方法加载时,该文件将定位并禁用它不需要的
链接
元素。它确保page2.css文件已启用,并保留它忽略的文件列表

(我把它放在
ready
handler函数中,但我倾向于在WinJS.Navigation事件的处理程序中使用这种技术,并依赖一致的文件命名来获得我想要的结果)


卸载
定义(“/page2.html”{
就绪:函数(){
var ignoreList=[“/css/ui dark.css”、“/css/ui light.css”、“/css/default.css”];
var myCSS=“/css/page2.css”;
WinJS.Utilities.query(“link”).forEach(函数(linkElem){
如果(linkElem.href.indexOf(myCSS)>-1){
linkElem.disabled=false;
}否则{
var ignore=false;
ignoreList.forEach(函数(ignoreItem){
if(linkElem.href.indexOf(ignoreItem)>-1){
忽略=真;
}
});
如果(!忽略){
linkElem.disabled=true;
}
}
});
}
});
改变

不卸载JavaScript和CSS是一个深思熟虑的选择,不是意外或疏忽

首先,要了解页面控件纯粹是一种JavaScript构造——浏览器引擎对它们一无所知。浏览器只看到由脚本动态生成的DOM块

web平台不允许您卸载脚本文件——一旦它们加载到上下文中,它们就永远存在

有了CSS,他们本可以尝试删除标签,但这会带来很多麻烦。根据导航到的订单页面,您可能会在同一个应用程序中应用不同的样式。如果两个页面引用同一个样式表怎么办?是否添加两次相同的链接标记?你要移除哪一个

一团糟。相反,WinJS保证脚本和样式表在第一次被引用时只加载一次。因此,你可以让应用程序中的每个页面都引用“myStyles.css”,并且只加载一次(并且只有一个样式标记)

那么,如何防止您看到的问题呢?首先,请记住,您正在构建一个应用程序,而不是一个任意增加新内容的网站。决定你的一般风格和类别。将共享样式放在default.css中,并从default.html文件中引用它

对于单个页面,最简单的方法是在样式前面加上页面名称。而不是:

<div class='intro'></div>


那么你就可以保证避免碰撞

如果您是按ID引用页面元素,那么不要这样做。在页面中使用ID会导致各种潜在的奇怪(如果同时呈现同一个页面控件两次会怎么样?而且,在页面加载到DOM中之前,ID不存在,这意味着按ID引用的数据win选项不起作用)。但是,如果你坚持,再考虑把IDS和页面预先编好。


基本上,设置临时名称空间以避免冲突。这比手动撕下链接标签容易得多,而且比进行完整导航会带来更好的应用体验。

这可能是一个很好的解决方案,使用约定名称:

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;
        }
        }
});

我得到了单页模型,我只是觉得MS更聪明一些,当你导航离开内部页面时,可以卸载它们的资源。是的,我知道我可以这样做,但这正是我试图避免硬编码的原因。我可能只是切换到多页实现,没有任何单独部分的css,每个母版页都将是一个模板,所有css都在一个文件中,然后加载的子页将没有任何自己的css。脚本文件不是这样的问题,很容易命名函数以避免冲突,或者只使用WinJS.Namespace,但是css文件可以被卸载,这似乎是明智的。事实上,似乎每个人都已经接受了这样一个观点:给所有css类命名是一种可行的方法,这真的是一种彻底的攻击。。。至少这是经过深思熟虑的,但从长远来看,我相信这是微软将受到批评的另一件事。我不确定除了在e
<div class='page1-intro'></div>
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;
        }
        }
});