控件(使用 JavaScript 的 HTML)

将新功能添加到 Windows 应用商店应用,例如自定义命令和增强的导航支持,以及 Windows 8.1 中的全新 HTML 和 JavaScript 控件。 对现有控件的更新可以让这些控件更易于使用并增加更多功能,如拖放操作支持。 这些新控件和控件更新让创建功能齐全的应用变得前所未有的简单。

新控件和控件更新

Windows 8.1 和 Windows JavaScript 库 2.0 中引入了以下新控件和功能:

Windows 8.1 和 Windows JavaScript 库 2.0 中包含对以下现有控件的更新:

使用 Windows JavaScript 库 2.0

新的 Microsoft Visual Studio 2013 项目会自动包含 Windows JavaScript 库 2.0。若要在使用 Windows 8 创建的项目中使用 Windows JavaScript 库 2.0,请替换现有的 Windows JavaScript 库 1 引用。


    <!-- WinJS style sheets (include one) -->
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet">
    <link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet">

    <!-- WinJS code -->
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

对 Windows JavaScript 库 2.0 的引用。


    <!-- WinJS style sheets (include one) -->
    <link rel="stylesheet" href="//Microsoft.WinJS.2.0/css/ui-dark.css" />
    <link rel="stylesheet" href="//Microsoft.WinJS.2.0/css/ui-light.css" />

    <!-- WinJS code -->
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

Visual Studio 2013 可以自动为你升级项目,你也可以手动完成以下更新:

  • 向项目中添加对适用于 JavaScript 的 Windows 8.1 库的引用。

  • 在你的应用清单中,将 OSMinVersionOSMaxVersionTested 值更新为 6.3.0:

    
      <Prerequisites>
        <OSMinVersion>6.3.0</OSMinVersion>
        <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
      </Prerequisites>
    
    

AppBarCommand

[立即获取 HTML AppBar 控件示例。]

在 Windows 8.1 中,你可以使用一种名为“内容”的新型 AppBarCommand,在使用 JavaScript 的 Windows 应用商店应用中创建自定义应用栏命令。

此功能通过允许你在 commands 布局中放置自定义内容,从而简化了使用自定义内容创建应用栏的过程。你可以利用对使用自定义内容的应用栏命令的全面内置支持,包括键盘操作、命令定位,以及用于动态显示和隐藏命令的动画。

放入到 commands 布局中后,内容类型 AppBarCommand 支持很多与默认应用栏命令相同的功能。

  • 在默认应用栏命令和自定义 AppBarCommand 之间已启用键盘操作(Tab 键、箭头键、Home 键以及 End 键)。

  • 新的内容类型 AppBarCommand 能够正常使用应用栏可伸缩性。应用在被缩小之后会动态放弃文本标签。

BackButton

Windows 8.1 和 Windows JavaScript 库 2.0 会以应用的控件形式向平台添加更多导航支持。这些控件之一就是 BackButton

BackButton 为你提供一个向自己的应用中添加向后导航功能的简单方法。创建一个 BackButton 控件很简单。


<button data-win-control="WinJS.UI.BackButton" ></button>

新 BackButton 控件

BackButton 会自动检查导航堆栈,以确定用户是否可以向后导航。如果没有可向后导航的内容,此按钮会自动禁用。当用户单击此按钮或使用键盘快捷方式(如 Alt+ 向左键或 BrowserBack 键)时,它会自动调用 WinJS.Navigation.back 函数以向后导航。你无需编写任何代码。

Hub(中心)

[立即获取 HTML 中心控件示例。]

为了帮助提供更加一致的导航体验,Windows 8.1 和 Windows JavaScript 库 2.0 中添加了 Hub 控件。

很多 Windows 应用商店应用都使用中心导航模式,即一种分层的导航系统。此模式最适合具有大量内容或许多不同部分内容供用户浏览的应用。

中心设计的实质是将内容分为不同的部分和不同级别的详细信息。 中心页是用户进入应用的入口点。此处的内容显示在一个水平平移或垂直平移的平移视图中,这样用户一眼就能看见新增内容和可用功能。 中心由不同类别的内容构成,每个类别映射到应用的部分页中。每个部分都应该显示内容或功能。中心应该提供许多可以看到的变化,吸引用户,并将他们吸引到应用的各个部分。

中心页

 

使用 Windows 8.1,Hub 控件可以更轻松地创建中心页。若要开始快速创建带有 Hub 页的应用,请使用 Visual Studio 2013 中的“中心应用”模板。

创建中心

若要创建中心,你需要为中心包含的每个部分添加一个 Hub 控件和一个 HubSection 对象。每个 HubSection 都可以包含任何类型的内容,包括其他 Windows JavaScript 库控件。你可以使用 header 属性来指定节标题。部分头文件可为静态或交互文件。交互式头文件显示可隐藏的 V 形图标,并在用户与它们交互时提升事件。

以下示例定义了一个包含三个部分的 Hub


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>hubPage</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <link href="/css/default.css" rel="stylesheet" />
    <link href="/pages/hub/hub.css" rel="stylesheet" />
    <script src="/js/data.js"></script>
    <script src="/pages/hub/hub.js"></script>
</head>
<body>
    <div class="hubpage fragment">
        <header aria-label="Header content" role="banner">
            <button data-win-control="WinJS.UI.BackButton"></button>
            <h1 class="titlearea win-type-ellipsis">
                <span class="pagetitle">Hub example</span>
            </h1>
        </header>

        <section class="hub" aria-label="Main content" role="main" data-win-control="WinJS.UI.Hub">
            <!-- Customize the Hub control by modifying the HubSection controls here. -->


            <div class="section1" data-win-control="WinJS.UI.HubSection" data-win-options="{ isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section1'} }">
                <img src="/images/gray.png" width="420" height="280" />
                <div class="subtext win-type-x-large secondary-text" data-win-res="{ textContent: 'Section1Subtext' }"></div>
                <div class="win-type-medium" data-win-res="{ textContent: 'DescriptionText' }"></div>
                <div class="win-type-small secondary-text">
                    <span data-win-res="{ textContent: 'Section1Description' }"></span>
                    <span data-win-res="{ textContent: 'Section1Description' }"></span>
                    <span data-win-res="{ textContent: 'Section1Description' }"></span>
                </div>
            </div>

            <div class="section2" data-win-control="WinJS.UI.HubSection" data-win-res="{ winControl: {'header': 'Section2'} }"
                data-win-options="{ onheaderinvoked: HubPage.section2HeaderNavigate }">
                <div class="itemTemplate" data-win-control="WinJS.Binding.Template">
                    <img src="#" data-win-bind="src: backgroundImage; alt: title" />
                    <div class="item-text">
                        <div class="win-type-medium" data-win-bind="textContent: title"></div>
                        <div class="win-type-xx-small secondary-text" data-win-bind="textContent: subtitle"></div>
                        <div class="win-type-small secondary-text" data-win-bind="textContent: description"></div>
                    </div>
                </div>
                <div class="itemslist" data-win-control="WinJS.UI.ListView" data-win-options="{
                        layout: {type: WinJS.UI.ListLayout2},
                        selectionMode: 'none',
                        itemTemplate: select('.section2 .itemTemplate'),  
                        itemDataSource: HubPage.section2DataSource,
                        oniteminvoked: HubPage.section2ItemNavigate
                    }">
                </div>
            </div>

            <div class="section3" data-win-control="WinJS.UI.HubSection" data-win-options="{ isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section3'} }">
                <div class="top-image-row">
                    <img src="/images/gray.png" />
                </div>
                <div class="sub-image-row">
                    <img src="/images/gray.png" />
                    <img src="/images/gray.png" />
                    <img src="/images/gray.png" />
                </div>
                <div class="win-type-medium" data-win-res="{ textContent: 'DescriptionText' }"></div>
                <div class="win-type-small secondary-text">
                    <span data-win-res="{ textContent: 'Section3Description' }"></span>
                    <span data-win-res="{ textContent: 'Section3Description' }"></span>
                </div>
            </div>


        </section>
    </div>
</body>
</html>

该代码创建此页面。

中心页

 

单击第二个标题时,应用会转到第二页。

部分页

 

以下代码执行导航。


(function () {
    "use strict";

    var nav = WinJS.Navigation;
    var session = WinJS.Application.sessionState;
    var util = WinJS.Utilities;

    // Get the groups used by the data-bound sections of the hub.
    var section2Group = Data.resolveGroupReference("group1");
    var section5Group = Data.resolveGroupReference("group6");

    WinJS.UI.Pages.define("/pages/hub/hub.html", {
        // This function is called whenever a user navigates to this page. It
        // populates the page elements with the app's data.
        ready: function (element, options) {
            var hub = element.querySelector(".hub").winControl;
            hub.onloadingstatechanged = function (args) {
                if (args.srcElement === hub.element && args.detail.loadingState === "complete") {
                    this._hubReady(hub);
                    hub.onloadingstatechanged = null;
                }
            }.bind(this);

            hub.onheaderinvoked = function (args) {
                args.detail.section.onheaderinvoked(args);
            };

            // TODO: Initialize the page here.
        },

        unload: function () {
            // TODO: Respond to navigations away from this page.
            session.hubScroll = document.querySelector(".hub").winControl.scrollPosition;
        },

        updateLayout: function (element, viewState, lastViewState) {
            /// <param name="element" domElement="true" />

            // TODO: Respond to changes in viewState.
        },

        _hubReady: function (hub) {
            /// <param name="hub" type="WinJS.UI.Hub" />

            WinJS.Resources.processAll();
            if (typeof session.hubScroll === "number") {
                hub.scrollPosition = session.hubScroll;
            }

            // TODO: Initialize the hub sections here.
        },
    });

    function createHeaderNavigator(group) {
        return util.markSupportedForProcessing(function (args) {
            nav.navigate("/pages/section/section.html", { title: this.header, groupKey: group.key });
        });
    }

    function createItemNavigator(group) {
        var items = Data.getItemsFromGroup(group);
        return util.markSupportedForProcessing(function (args) {
            var item = Data.getItemReference(items.getAt(args.detail.itemIndex));
            nav.navigate("/pages/item/item.html", { item: item });
        });
    }

    function getItemsDataSourceFromGroup(group) {
        return Data.getItemsFromGroup(group).dataSource;
    }

    WinJS.Namespace.define("HubPage", {
        section2DataSource: getItemsDataSourceFromGroup(section2Group),
        section2HeaderNavigate: createHeaderNavigator(section2Group),
        section2ItemNavigate: createItemNavigator(section2Group),
        section5DataSource: getItemsDataSourceFromGroup(section5Group),
        section5ItemNavigate: createItemNavigator(section5Group)
    });
})();

你甚至可使用 Hub 控件和 SemanticZoom 控件。有关此控制和更多的示例,请参阅 HTML 中心控件示例

ItemContainer

[立即获取 HTML ItemContainer 示例。]

新的 ItemContainer 控件可简化交互元素的创建过程,这些元素提供了轻扫、拖放以及悬停功能。只需将你的内容放到 ItemContainer 中即可。ItemContainer 可以包含标准 HTML 元素,甚至其他 WinJS 控件。

ItemContainer 很灵活,从而使其非常适合很多用途,如创建内容丰富的复选框组、导航按钮,以及购物车表示。

导航栏中的 ItemContainer 对象

 

当你希望显示项目,但又不需要使用全部 ListView 功能时,可以使用 ItemContainer 控件。

使用 ItemContainer

以下示例将创建两个 ItemContainer 对象,并将它们的 tapBehavior 属性设置为 toggleSelect 以便可以被选择。


<div id="item1"
    data-win-control="WinJS.UI.ItemContainer"
    data-win-options="{tapBehavior: 'toggleSelect'}"
    style="width: 300px;">
    <div style="margin: 10px; padding: 10px; background-color: lightgray">
        <div class="win-type-x-large"
            style="margin-bottom: 5px;">
            Banana
        </div>
        <img src="/images/60banana.png">
        <div>Frozen yogurt</div>
    </div>
</div>
<div id="item2"
    data-win-control="WinJS.UI.ItemContainer"
    data-win-options="{tapBehavior: 'toggleSelect'}"
    style="width: 300px;">
    <div style="margin: 10px; padding: 10px; background-color: lightgray">
        <div class="win-type-x-large"
            style="margin-bottom: 5px;">
            Strawberry
        </div>
        <img src="/images/60Strawberry.png">
        <div>Ice cream</div>
    </div>
</div>

两个 ItemContainer 对象

 

你还可以将一个 ItemContainer 与一个 Repeater 控件一起使用以从 List 生成项目:只需将 ItemContainer 放入你的 Template 控件中即可。


<div id="itemTemplate" data-win-control="WinJS.Binding.Template">
    <div  
        data-win-control="WinJS.UI.ItemContainer" 
        data-win-options="{tapBehavior: WinJS.UI.TapBehavior.toggleSelect}"
        style="width: 300px;">
            <div 
                 style=" margin: 10px; padding: 10px; background-color: lightgray">
                <div class="win-type-x-large" 
                    style="margin-bottom: 5px;" 
                    data-win-bind="textContent: title"></div>
                <img src="#" data-win-bind="src: image">
		        <div data-win-bind="textContent: desc"></div>
            </div>
    </div>
</div>

<div data-win-control="WinJS.UI.Repeater" 
    data-win-options="{data: ItemContainerExample.flavorList, 
    template: select('#itemTemplate')}">
</div>

以下示例定义了数据源。


(function () {
    "use strict";

    var basicList = new WinJS.Binding.List(
        [
            { title: "Banana blast", desc: 'Frozen yogurt', image: '/images/60Banana.png'  },
            { title: "Strawberry swirl", desc: 'Ice cream', image: '/images/60Strawberry.png' },
            { title: "Magnificant mint", desc: 'Frozen yogurt', image: '/images/60Mint.png' },
            { title: "Lemon lift", desc: 'Frozen yogurt', image: '/images/60Lemon.png' }
        ]);

    WinJS.Namespace.define("ItemContainerExample",
        {
            flavorList: basicList

        });
})();

Repeater 生成的 ItemContainer 对象

 

默认情况下可以选择项目。若要禁用选择,请将 ItemContainer 控件的 selectionDisabled 属性设置为 true

NavBar

[立即获取 HTML NavBar 控件示例。]

Windows 8.1 和 Windows JavaScript 库 2.0 中引入了以下新控件,帮助你提供一致且可预测的导航体验:WinJS.UI.NavBar 控件。

包含从数据源生成的导航项目的 NavBar

 

NavBar 类似于专用于导航命令的 AppBar。(实际上,NavBarAppBar 的子类。)它可以包含一系列简单的链接,也可以包含分类显示的多个级别的链接。你可以使用以下方法填充 NavBar:硬编码条目、以编程方式更新它,或者使用数据绑定。

NavBar 会在用户需要时显示在应用屏幕的页首。用户可以通过以下方式调用 NavBar:执行边缘轻扫、按 Windows 徽标键 + Z,或者右键单击。

NavBar 还支持垂直布局和拆分的导航项(具有子导航选项的导航项)。NavBar 是一个高度可自定义的对象:你可以使用级联样式表 (CSS) 设计 NavBar 及其内容的几乎所有方面的样式,还可以创建自定义导航项。

创建 NavBar

NavBar 包括三个组件:

  • NavBar 自身。

  • NavBarContainer 对象,它包含导航项(NavBarCommand 对象),并支持分页以及平移和滚动。在一个 NavBar 中可以包含一个或多个 NavBarContainer 对象。可以使用 NavBarContainer 对象来定义导航选项组。

  • 一个或多个 NavBarCommand 对象。 这些是用户单击可以导航的内容。

若要启用导航,你可以设置 NavBarCommand 对象的 location 属性。用户单击命令时,WinJS.Navigation.navigated 事件启动。 使用此事件导航到指定的位置。

也可以在 NavBar 上注册 oninvoked 事件,并使用你的事件处理程序执行导航操作。

以下示例显示了一个包含两个导航项的简单 NavBar


<div id="NavBar" data-win-control="WinJS.UI.NavBar">
    <div id="GlobalNav" data-win-control="WinJS.UI.NavBarContainer">
            <div data-win-control="WinJS.UI.NavBarCommand" data-win-options="{
                label: 'Home',
                icon: WinJS.UI.AppBarIcon.home,
                location: '/html/home.html',
                splitButton: false
                }">
            </div>
            <div data-win-control="WinJS.UI.NavBarCommand" data-win-options="{
                label: 'Your apps',
                icon: WinJS.UI.AppBarIcon.favorite,
                location: '/html/yourapps.html',
                splitButton: false
                }">
            </div>
    </div>
</div>


NavBar 如下所示。

NavBar

 

可创建包含子 NavBarCommand 对象的 NavBarCommand。要这样做,请将父 NavBarCommand 对象的 splitButton 属性设置为 true,然后使用 splittoggle 事件显示一个包含子 NavBarCommand 对象的 Flyout。此处是其第一个部分的示例代码。


<div id="useSplit" data-win-control="WinJS.UI.NavBar">
    <div class="globalNav" data-win-control="WinJS.UI.NavBarContainer">
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Home', icon: 'url(../images/homeIcon.png)' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Favorite', icon: WinJS.UI.AppBarIcon.favorite, splitButton: 'true' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Your account', icon: WinJS.UI.AppBarIcon.people }">
        </div>
    </div>
</div>
<div id="contactFlyout" data-win-control="WinJS.UI.Flyout" 
    data-win-options="{ placement: 'bottom' }">
    <div id="contactNavBarContainer" data-win-control="WinJS.UI.NavBarContainer"}">
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Family' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Work' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Friends' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
            data-win-options="{ label: 'Blocked' }">
        </div>  
    </div>
</div>

下一个示例显示了可初始化 HTML 页面,并添加 splittoggle 事件处理程序的代码,此事件处理程序可显示包含子 NavBarCommand 对象的 Flyout


(function () {
    "use strict";
    var navcontainer;

    var page = WinJS.UI.Pages.define("/html/6-UseSplitButton.html", {
        ready: function (element, options) {
            document.body.querySelector('#useSplit').addEventListener('invoked', this.navbarInvoked.bind(this));
            document.body.querySelector('#contactNavBarContainer').addEventListener('invoked', this.navbarInvoked.bind(this));

            var navBarContainerEl = document.body.querySelector('#useSplit .globalNav');
            if (navBarContainerEl) {
                this.setupNavBarContainer();
            } else {
                var navBarEl = document.getElementById('useSplit');
                navBarEl.addEventListener('childrenprocessed', this.setupNavBarContainer.bind(this));
            }
        },

        navbarInvoked: function (ev) {
            var navbarCommand = ev.detail.navbarCommand;
            WinJS.log && WinJS.log(navbarCommand.label + " NavBarCommand invoked", "sample", "status");
            document.querySelector('select').focus();
        },

        setupNavBarContainer: function () {
            var navBarContainerEl = document.body.querySelector('#useSplit .globalNav');

            navBarContainerEl.addEventListener("splittoggle", function (e) {
                var flyout = document.getElementById("contactFlyout").winControl;
                var navbarCommand = e.detail.navbarCommand;
                if (e.detail.opened) {
                    flyout.show(navbarCommand.element);
                    var subNavBarContainer = flyout.element.querySelector('.win-navbarcontainer');
                    if (subNavBarContainer) {
                        // Switching the navbarcontainer from display none to display block requires 
                        // forceLayout in case there was a pending measure.
                        subNavBarContainer.winControl.forceLayout();
                        // Reset back to the first item.
                        subNavBarContainer.currentIndex = 0;
                    }
                    flyout.addEventListener('beforehide', go);
                } else {
                    flyout.removeEventListener('beforehide', go);
                    flyout.hide();
                }
                function go() {
                    flyout.removeEventListener('beforehide', go);
                    navbarCommand.splitOpened = false;
                }
            });
        }
    });
})();

(有关完整的代码,请参阅 HTML NavBar 示例。)

拆分按钮打开时的 NavBar 如下所示:

拆分 NavBarCommand

 

你可以将 NavBarContainer 绑定到数据源。为此,请创建一个包含描述导航命令的数据的 List,并将该列表用于设置 NavBarContainer 对象的 data 属性。以下示例定义供 NavBarContainer 使用的数据。



(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/2-UseData.html", {
        init: function (element, options) {
            var categoryNames = ["Picks for you", "Popular", "New Releases", "Top Paid", "Top Free",
            "Games", "Social", "Entertainment", "Photo", "Music & Video",
            "Sports", "Books & Reference", "News & Weather", "Health & Fitness", "Food & Dining",
            "Lifestyle", "Shopping", "Travel", "Finance", "Productivity",
            "Tools", "Secuirty", "Business", "Education", "Government"];

            var categoryItems = [];
            for (var i = 0; i < categoryNames.length; i++) {
                categoryItems[i] = {
                    label: categoryNames[i]
                };
            }

            Data.categoryList = new WinJS.Binding.List(categoryItems);
        },

        ready: function (element, options) {
            document.body.querySelector('#useTemplate').addEventListener('invoked', this.navbarInvoked.bind(this));
        },

        navbarInvoked: function (ev) {
            var navbarCommand = ev.detail.navbarCommand;
            WinJS.log && WinJS.log(navbarCommand.label + " NavBarCommand invoked", "sample", "status");
            document.querySelector('select').focus();
        }
    });
})();



下一个示例显示了可创建 NavBarNavBarContainer 对象的 HTML。



<div id="useTemplate" data-win-control="WinJS.UI.NavBar">
    <div class="globalNav" data-win-control="WinJS.UI.NavBarContainer">
        <div data-win-control="WinJS.UI.NavBarCommand" 
             data-win-options="{ label: 'Home', icon: 'url(../images/homeIcon.png)' }">
        </div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
             data-win-options="{ label: 'Favorite', icon: 'favorite' }"></div>
        <div data-win-control="WinJS.UI.NavBarCommand" 
             data-win-options="{ label: 'Your account', icon: 'people' }"></div>
    </div>
    <div class="categoryNav" 
        data-win-control="WinJS.UI.NavBarContainer" 
        data-win-options="{ data: Data.categoryList, maxRows: 3 }">
    </div>
</div>



(有关完整的代码,请参阅 HTML NavBar 示例。)

运行此代码时,它会创建此 NavBar

包含从数据源生成的导航项目的 NavBar

 

尽管此处没有显示,你仍可以使用 WinJS.Binding.Template 对象和数据源来生成导航栏项目。

Repeater

[立即获取 HTML Repeater 控件示例。]

Repeater 是一个简单易用的 WinJS 控件,该控件使用模板从一组数据中生成 HTML 标记。此模板可以包含几乎所有 HTML 标记和 WinJS 控件。你甚至可以在 Repeater 控件中嵌套 Repeater 控件。

使用 Repeater 可以生成自定义列表和表格。以下是一个由 Repeater 创建的天气预报示例。

repeater 控件

 

Repeater 不是 ListView 控件的替代控件。它更灵活,但却不提供 ListView 所具备的一些高级功能,比如对如何加载数据项的控制。

使用 Repeater

RepeaterList 中生成其数据。以下示例将创建一个包含一些简单项的 List


(function () {
    "use strict";

    var basicList2 = new WinJS.Binding.List(
        [
            { title: "Item 1" },
            { title: "Item 2" },
            { title: "Item 3" },
            { title: "Item 4" }
        ]);

    WinJS.Namespace.define("RepeaterExample",
        {
            basicList: basicList2

        });
})();

要指定 Repeater 生成的标记,你可以定义一个 template。你可以创建一个标记模板或使用模板化功能。此示例可创建标记模板。 它通过数据绑定的方式将数据源的标题域绑定到 li 元素的文本内容。


<div id="listTemplate" data-win-control="WinJS.Binding.Template">
    <li data-win-bind="textContent: title"></li>
</div>

下一示例将创建 Repeater 自身。


<ul data-win-control="WinJS.UI.Repeater" 
    data-win-options="{data: RepeaterExample.basicList, 
    template: select('#listTemplate')}">
</ul>

当你运行此应用时,Repeater 会为数据列表中的每一项生成一个 li 元素。

Repeater 控件生成的列表

 

带有 SmartScreen 筛选器的 WebView

[立即获取 HTML WebView 控件示例。]

在 Windows 8 中,你可以使用 iframe 元素来托管基于 Web 的内容,但它无法提供很多内容隔离或导航功能。Windows 8.1 中引入了新的 WebView 控件,此控件可大大简化托管你的应用中基于 Web 内容的过程。

以下是一些 WebView 通过使用 iframe 显示基于 Web 的内容提供的改进:

  • 支持 HTML5

    WebView 中托管的页面可访问大部分 HTML5 功能。(但是WebView 不能访问 IndexedDBHTML5 应用缓存地理位置 APIClipboard API。)

  • 改进的导航支持

    WebView 有其自己单独的历史记录堆栈,并提供多种向前导航,向后导航,以及重新加载当前页的方法。

  • 支持在帧中无法使用的站点

    WebView 可以显示在 frameiframe 元素中无法使用的站点。

使用 WebView 加载内容

若要创建 WebView 控件,你需要创建一个 x-ms-webview 元素。


<x-ms-webview id="webview">
</x-ms-webview>


你可以通过多种方式使用 WebView 加载内容:

  • 使用 WebView 控件的 src 属性、navigate 方法或 navigateWithHttpRequestMessage 方法导航到 URI。 本例使用 src 属性导航到 URI。

    
    <x-ms-webview id="webview" src="http://go.microsoft.com/fwlink/p/?LinkID=294155" 
        style="width: 400px; height: 400px;">
    </x-ms-webview>
    
    
    
  • 使用 navigateToString 方法来加载任意 HTML 字符串。

    
    var htmlString = "<!DOCTYPE html>" +
            "<html>" +
            "<head><title>Simple HTML page</title></head>" +
            "<body>" +
                "<h1>Hi!</h1>" +
                "<p>This is a simple HTML page.</p>" +
            "</body>" +
            "</html>";
    document.getElementById("webview").navigateToString(
        htmlString);
    
    
  • 你可以使用 navigate 方法和 ms-appdata:// 协议来加载存储在应用的状态文件夹中的 HTML 内容。

    
     document.getElementById("webview").navigate(
        "ms-appdata:///local/NavigateToState/simple_example.html");
    
    
  • 对于基于 HTML 的文件格式,它有时可以用于根据需要流式传输相对引用,如 WebView 控件本身无法呈现的加密 HTML 内容。使用 buildLocalStreamUrinavigateToLocalStreamUri 方法来显示媒体流中的内容。(你还必须实施一个使用 IUriToStreamResolver 接口的自定义 Windows 运行时对象。)

    
    var contentUri = document.getElementById("webview").buildLocalStreamUri(
        "NavigateToStream", "simple_example.html");
    var uriResolver = new SDK.WebViewSampleCS.StreamUriResolver();
    document.getElementById("webview").navigateToLocalStreamUri(contentUri, uriResolver);
    
    

有关完整的示例,请参阅 HTML WebView 示例

对 ListView 的拖放操作支持

[立即获取 HTML ListView 拖放和重新排序示例。]

对于 Windows JavaScript 库 2.0,ListView 添加了对拖放操作的支持。这个新的支持与 HTML 5 拖放操作兼容。你可以在两个 ListView 控件之间,在一个 ItemContainer 和一个 ListView 之间,以及在任何 HTML 元素和 ListView 之间进行拖动。你可以通过在添加新项目后重新排序 ListView 控件的项目,让用户将项目拖放到 ListView 中的特定位置,也可以控制将拖放的项目插入到哪里。

从 ListView 拖动项目

若要启用将 ListView 中的项目拖动到 HTML 5 中的某个目标位置的操作,请完成以下操作:

  1. ListViewitemsDraggable 属性设置为 true

  2. 处理 ListView 控件的 itemdragstart 事件。在你的事件处理程序中,从事件对象的 detail 属性中获取一个 dataTransfer 对象。使用 dataTransfer 对象的 setData 方法来指定如何传输数据,以及传输哪些数据。

  3. 处理拖放目标的 dragover 事件。在你的事件处理程序中,使用 event 对象的 preventDefault 方法来告知系统你可接受拖放操作。否则,拖放目标将不接受拖放操作。

  4. 处理拖放目标的 drop 事件。在你的事件处理程序中,从事件对象的 detail 属性中获取一个 dataTransfer 对象。使用 dataTransfer 对象的 getData 属性检索传输的数据。使用此数据来更新拖放目标。 请谨慎操作,不要接受来自你的应用中本身可拖动项目的拖放内容,如选择的文本和 img 元素。

以下一组示例说明了如何启用从 ListView 中拖动项目的操作。第一个示例定义了 HTML 标记。


<div id="myDropTarget" class="DnDItem">
    <div id="myTargetContents">
        <p>
            HTML 5 Drop Target
        </p>
        <br />
        <div id="myPlusSign" class="drop-ready">+ </div>
        <br />
        <p>
            Drop Items Here
        </p>
    </div>
</div>

<!-- Simple template for the ListView instantiation  -->
<div id="smallListIconTextTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="smallListIconTextItem">
        <img src="#" class="smallListIconTextItem-Image" data-win-bind="src: picture" draggable="false" />
        <div class="smallListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<!-- The declarative markup necessary for ListView instantiation -->
<!-- Call WinJS.UI.processAll() in your initialization code -->
<div id="listView"
    class="win-selectionstylefilled"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{ 
        itemDataSource: myData.dataSource,
        selectionMode: 'none', 
        itemTemplate: smallListIconTextTemplate,
        itemsDraggable: true,
        layout: { type: WinJS.UI.GridLayout } 
    }">
</div>

下面是拖放操作的 CSS。


.drop-ready #myPlusSign
{
    opacity: 1;
}

#myPlusSign
{
     font-size:100px;
     font-weight:bolder;
     color: blue;
     opacity: 0;
}

下一个示例显示了可启用拖放功能的代码。


(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/scenario2.html", {
        ready: function (element, options) {

            listView.addEventListener("itemdragstart", function (eventObject) {
                eventObject.detail.dataTransfer.setData("Text", JSON.stringify(eventObject.detail.dragInfo.getIndices()));
            });

            var dropTarget = element.querySelector("#myDropTarget");
            dropTarget.addEventListener("dragover", function (eventObject) {
                // Allow HTML5 drops.
                eventObject.preventDefault();
            });

            dropTarget.addEventListener("dragenter", function (eventObject) {
                WinJS.Utilities.addClass(dropTarget, "drop-ready");
            });

            dropTarget.addEventListener("dragleave", function (eventObject) {
                WinJS.Utilities.removeClass(dropTarget, "drop-ready");
            });

            dropTarget.addEventListener("drop", function (eventObject) {
                // Get indicies -> keys of items that were trashed, and remove from datasource.
                WinJS.Utilities.removeClass(dropTarget, "drop-ready");
                var indexSelected = JSON.parse(eventObject.dataTransfer.getData("Text"));
                var listview = document.querySelector("#listView").winControl;
                var ds = listview.itemDataSource;

                ds.itemFromIndex(indexSelected[0]).then(function (item) {
                    WinJS.log && WinJS.log("You dropped the item at index " + item.index + ", "
                    + item.data.title, "sample", "status");
                });
            });

        }
    });

})();


有关完整代码,请参阅 HTML ListView 拖放操作和重新排序示例

将项目拖放到 ListView 中

若要将元素拖放到 ListView 中的某个特定位置,请完成以下操作:

  1. 将 HTML 元素(拖放源)的 draggable 属性设置为 true

  2. 处理拖放目标的 dragstart 事件。 在你的事件处理程序中,从事件对象中获取一个 dataTransfer 对象。使用 dataTransfer 对象的 setData 方法来指定如何传输数据,以及传输哪些数据。

  3. 处理 ListView 控件的 itemdragenter 事件。在你的事件处理程序中,使用 event 对象的 preventDefault 方法来告知系统你可接受放置操作。否则,拖动操作可能会产生无法预料的结果。

  4. 处理 ListView 控件的 itemdragdrop 事件。 在你的事件处理程序中,从事件对象的 detail 属性中获取一个 dataTransfer 对象。使用 dataTransfer 对象的 getData 属性检索传输的数据。使用此数据来更新 ListView

以下一组示例说明了如何启用将项目拖放到 ListView 中的操作。第一个示例定义了 HTML 标记。


<div id="myDragSource" class="DnDItem">
    <div id="mySourceContents">
        <p>
            HTML 5 Drag Source
        </p>
        <br />
        <br />
        <br />
        <div id="myDragContent" class="smallListIconTextItem" draggable="true">
            <img id="myImg" src="/images/60Tree.png" class="smallListIconTextItem-Image" draggable="false" />
            <div class="smallListIconTextItem-Detail">
                <h4 id="myItemTitle">Drag Me</h4>
            </div>
        </div>
    </div>
</div>

<!-- Simple template for the ListView instantiation  -->
<div id="smallListIconTextTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="smallListIconTextItem">
        <img src="#" class="smallListIconTextItem-Image" data-win-bind="src: picture" draggable="false" />
        <div class="smallListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<!-- The declarative markup necessary for ListView instantiation -->
<!-- Call WinJS.UI.processAll() in your initialization code -->
<div id="listView"
    class="win-selectionstylefilled"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{ 
        itemDataSource: myData.dataSource,
        selectionMode: 'none',
        itemTemplate: smallListIconTextTemplate,
        itemsReorderable: true,
        layout: { type: WinJS.UI.GridLayout } 
    }">
</div>

下一个示例显示了可启用拖放功能的代码。


(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/scenario3.html", {
        ready: function (element, options) {

            myDragContent.addEventListener("dragstart", function (eventObject) {
                var dragData = { sourceElement: myDragContent.id, data: myItemTitle.innerText, imgSrc: myImg.src };
                eventObject.dataTransfer.setData("Text", JSON.stringify(dragData));
            });

            listView.addEventListener("itemdragenter", function (eventObject) {
                if (eventObject.detail.dataTransfer.types.contains("Text")) {
                    eventObject.preventDefault();
                }
            });

            listView.addEventListener("itemdragdrop", function (eventObject) {
                var dragData = JSON.parse(eventObject.detail.dataTransfer.getData("Text"));
                if (dragData && dragData.sourceElement === myDragContent.id) {
                    var newItemData = { title: dragData.data, text: ("id: " + dragData.sourceElement), 
                                        picture: dragData.imgSrc };
                    // insertAfterIndex tells us where in the list to add the new item.
                    // If we're inserting at the start, insertAfterIndex is -1. 
                    // Adding 1 to insertAfterIndex gives us the nominal index in the array to insert the new item.
                    myData.splice(eventObject.detail.insertAfterIndex + 1, 0, newItemData);
                } else {
                    // Throw error that illegal content was dropped.
                }
            });
        }
    });
})();


有关完整代码,请参阅 HTML ListView 拖放操作和重新排序示例

对 ListView 中的项目重新排序

能够重新排序内容可帮助用户增强控制感。 新的 itemsReorderable 属性使用户能够轻松对 ListView 中的项目顺序进行更改。只需将 itemsReorderable 设置为 true 即可允许用户在 ListView 中拖动项目;无需其他代码。

注意  若要在一个分组的 ListView 中完全启用重新排序项目操作,你还必须对 itemdragdrop 事件做出响应,并将项目插入到正确位置。
注意  若要使重新排序操作顺利进行,你的数据源必须支持重新排序。

以下示例将创建一个支持项目重新排序的 ListView


<style type="text/css">
    .win-listview {
        margin: 20px;
        border: 2px solid gray;
        Width: 500px; 
    }

    .standardItem {
        width: 150px;
        height: 150px;
        background-color: #0aaddd;
        padding: 5px; 
    }

</style>

<div id="template" data-win-control="WinJS.Binding.Template">
    <div class="standardItem" data-win-bind="textContent: title" ></div>
</div>
<div
    id="reorderableListView"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
    itemDataSource: ListViewExamples.dataList.dataSource, 
    itemTemplate: select('#template'), 
    layout: {type: WinJS.UI.GridLayout},
    itemsReorderable: true 
    }">
</div>

下一个示例定义了 ListView 使用的数据源。


(function () {
    "use strict";

    var dataList =
        new WinJS.Binding.List(
             [{ title: "Item 1" },
              { title: "Item 2" },
              { title: "Item 3" },
              { title: "Item 4" }]);

    WinJS.Namespace.define("ListViewExamples",
        {
            dataList: dataList
        })

})();


代码运行时,用户可以通过拖动 ListView 项目来对项目进行重新排序。

ListView 重新排序

新 ListView 布局:CellSpanningLayout

使用 Windows JavaScript 库 1.0 时,如果你希望 ListView 包含大小不同的项目,可以使用 GridLayout。对于 Windows JavaScript 库 2.0,我们添加了一个专门用于创建大小不同网格的新布局:CellSpanningLayout

以下示例为使用 CellSpanningLayoutListView 定义了数据源,以及 itemInfogroupInfo 方法。ListView 中的第一个项目最大为 510 像素,除此之外的所有其他项目大小均为 250 像素 X 250 像素。


(function () {
    "use strict";

    var unorderedList =
        new WinJS.Binding.List(
             [{ title: "Item 1", cssClass: "tallItem" },
              { title: "Item 2", cssClass: "standardItem" },
              { title: "Item 3", cssClass: "standardItem" },
              { title: "Item 4", cssClass: "standardItem" }]);

    function myItemInfo(itemIndex) {
        var size = { width: 250, height: 250 };
        if (itemIndex === 0) {
            size.height = 510;
        }

        return size;
    };

    function myGroupInfo(groupInfo) {
        return {
            enableCellSpanning: true,
            cellWidth: 250,
            cellHeight: 250
        };
    };

    WinJS.Utilities.markSupportedForProcessing(myItemInfo);
    WinJS.Utilities.markSupportedForProcessing(myGroupInfo);

    WinJS.Namespace.define("ListViewExamples",
        {
            unorderedList: unorderedList,
            myItemInfo: myItemInfo,
            myGroupInfo: myGroupInfo
        })


})();


下一个示例显示了用于创建 ListViewWinJS.Binding.Template 的 HTML。


<style type="text/css">
    .win-listview {
        margin: 5px;
        border: 2px solid gray; 
    }

    .standardItem {
        width: 250px;
        height: 250px;
        background-color: #999999;
        padding: 5px; 
    }

    .tallItem {
        width: 250px;
        height: 510px;
        background-color: #0aaddd;
        padding: 5px; 
    }
</style>

<div id="template" data-win-control="WinJS.Binding.Template">
    <div data-win-bind="className: cssClass; textContent: title" ></div>
</div>

<div
    id="cellSpanningListView"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
    itemDataSource: ListViewExamples.unorderedList.dataSource, 
    itemTemplate: select('#template'), 
    layout: {type: WinJS.UI.CellSpanningLayout, 
    itemInfo: ListViewExamples.myItemInfo, 
    groupInfo: ListViewExamples.myGroupInfo}
    }">
</div>


ListView 如下所示。

一个使用 CellSpanningLayout 的 ListView

其他 ListView 更新

Windows 8.1 包含了对 ListView 控件的更多改进。

改进了头文件的可访问性

分组的 ListView 中的标题现在支持键盘导航,以及键盘和鼠标插入。你无需进行任何代码更改即可获取这些新功能。

(有关创建组的详细信息,请参阅如何对 ListView 中的项进行分组。)

注意  如果你通过在 Windows JavaScript 库 1.0 中包含链接或按钮,将头文件设置为可调用,那么当你切换到 Windows JavaScript 库 2.0 时,用户将无法使用键盘调用此头文件。 若要解决此问题,请处理 ongroupheaderinvoked 事件,并使用该事件来执行头文件操作,而不是使用按钮或链接。

对布局接口的更新

ListView 现在有一组新的布局接口,使你能够更轻松地创建自己的自定义布局:ILayout2ISiteLayout2。实现这些接口时,你可以将标准 CSS 布局用作你的实现的一部分。

ListLayout 和 GridLayout 更新

我们已更新 ListLayoutGridLayout 以提高它们的整体性能,尤其是平移性能。你无需进行任何代码更改即可利用这些改进。

其他 WinJS 更新

绑定和 WinJS.Binding.Template 更新

Windows JavaScript 库 2.0 使用一个更加高效的全新系统来处理 Template 对象,这可以显著提高性能。这个全新的系统可以让数据绑定和控件实例化过程变得更为流畅,并且可以实现并行处理,无需再像使用 Windows JavaScript 库 1.0 那样需要串行完成。如果你的代码依靠传统的串行处理行为,我们建议更改你的代码以利用更快的模板处理。但如果你无法更改代码,可以使用 disableOptimizedProcessing 属性恢复原来的行为。

释放 API

释放模型是一种新模式,它允许元素和控件在其生存期结束时释放其资源,以防止内存泄漏。 元素或控件可以选择实现此模式。需要释放资源的 Windows JavaScript 库 2.0 控件现在可以实现此 API。

若要利用此释放模型,请在不再需要此控件时调用该控件的 dispose 方法,比如,当你导航离开某个页面,或关闭应用时。

 

 

显示:
© 2015 Microsoft