控制項 (HTML 搭配 JavaScript)

使用 Windows 8.1 中的新 HTML 和 JavaScript 控制項,將功能 (例如自訂命令和增強的瀏覽支援) 新增到您的 Windows 市集應用程式。 現有控制項的更新讓控制項更容易使用且新增了更多功能,例如拖放支援。 這些新的控制項和控制項更新讓您比過去更容易建立功能完整的應用程式。

新的控制項和控制項更新

Windows 8.1 和適用於 JavaScript 2.0 的 Windows Library 導入了下列新的控制項和功能:

Windows 8.1 和適用於 JavaScript 2.0 的 Windows Library 包含下列現有控制項的更新:

使用適用於 JavaScript 2.0 的 Windows Library

新的 Microsoft Visual Studio 2013 專案會自動包含適用於 JavaScript 2.0 的 Windows Library。若要在以 Windows 8 建立的專案中使用適用於 JavaScript 2.0 的 Windows Library,請取代現有適用於 JavaScript 1 的 Windows Library 參考。


    <!-- 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>

...以適用於 JavaScript 2.0 的 Windows Library 參考來取代:


    <!-- 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 Library 參考新增到專案。

  • 在應用程式資訊清單中,將 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 支援許多與預設應用程式列命令相同的功能。

  • 鍵盤操作 (使用 Tab 鍵、方向鍵、Home 鍵及 End 鍵) 已在預設應用程式列命令與自訂 AppBarCommand 之間啟用。

  • 應用程式列大小調整在新的內容類型 AppBarCommand 上正確運作。當應用程式調整為較小的尺寸時,會動態捨棄命令的文字標籤。

BackButton

Windows 8.1 和適用於 JavaScript 2.0 的 Windows Library 會以應用程式控制項的形式,為平台新增更多瀏覽支援。這些控制項的其中一個是 BackButton

BackButton 為您提供一個將向後瀏覽新增到應用程式的簡單方式。建立 BackButton 控制項很簡單。


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

新的 BackButton 控制項

BackButton 會自動檢查瀏覽堆疊,判斷使用者是否可以向後瀏覽。如果沒有可以向後瀏覽的內容,按鈕會自己停用。使用者按一下按鈕或使用鍵盤快速鍵 (如 Alt+Left 或 BrowserBack 鍵) 時,它會自動呼叫 WinJS.Navigation.back 函式以向後瀏覽。您不需要撰寫任何程式碼。

Hub

[立即取得 HTML Hub 控制項範例。]

為了協助提供更一致的瀏覽體驗,Windows 8.1 和適用於 JavaScript 2.0 的 Windows Library 新增了 Hub 控制項。

許多 Windows 市集應用程式都使用中樞瀏覽模式,它是一種階層式的瀏覽系統。這個模式最適合具有大型內容集合或許多相異內容區段的應用程式,讓使用者進行瀏覽。

中樞設計的精髓在於將內容分類到不同的區段和不同的詳細資料層級。 中樞頁面是使用者進入應用程式的入口。在這裡會以豐富的水平或垂直移動瀏覽檢視顯示內容,使用者可以藉此立即了解新的功能和可使用的功能。 中樞由不同內容類別組成,每個類別均對應至應用程式的區段頁面。每個區段都應該以泡泡形式顯示內容和功能。中樞應提供各式各樣的視覺呈現方式,吸引使用者並將他們的注意力引導至應用程式的其他部分。

中樞頁面

 

在 Windows 8.1 中,Hub 控制項可以讓您輕鬆地建立中樞頁面。若要快速開始建立包含 Hub 頁面的應用程式,請使用 Visual Studio 2013 中的 [中樞應用程式] 範本。

建立 Hub

若要建立中樞,您必須新增 Hub 控制項,並為中樞所含的每個區段新增一個 HubSection 物件。每個 HubSection 都可以包含任何類型的內容,包括其他適用於 JavaScript 的 Windows Library 控制項。您可以使用 header 屬性指定區段標頭。區段標頭可以是靜態的或是互動式。互動式標頭會顯示一個可隱藏的>形箭號,而且會在使用者與它們互動時引發事件。

這個範例定義了包含三個區段的 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 Hub 控制項範例

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 和適用於 JavaScript 2.0 的 Windows Library 導入了新的控制項,協助您提供一致且可預期的瀏覽經驗:WinJS.UI.NavBar 控制項。

包含自資料來源產生的瀏覽項目的 NavBar

 

NavBar 類似於 AppBar,專門用於瀏覽命令(事實上,NavBarAppBar 的子類別)。它可以包含簡單的連結清單,也可以包含組織成各個類別的數個連結層級。您可使用硬式編碼輸入、以程式設計方式更新,或使用資料繫結來填入 NavBar

當使用者需要的時候,NavBar 會顯示在應用程式畫面的頂端。使用者在邊緣撥動、按下 Windows 標誌鍵 + Z 或按一下滑鼠右鍵,就可叫用 NavBar

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

Repeater 會從 List 產生它的資料。這個範例會建立一個包含數個簡單項目的 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 內容:

使用 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/?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 拖放和重新排序範例。]

在適用於 JavaScript 2.0 的 Windows Library 中,ListView 新增了對拖放操作的支援。這個新支援與 HTML 5 拖放功能相容。您可以在兩個 ListView 控制項之間、ItemContainerListView 之間,以及任何 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

在適用於 JavaScript 1.0 的 Windows Library 中,如果您想要 ListView 包含多種大小的項目,要使用 GridLayout。而在適用於 JavaScript 2.0 的 Windows Library 中,我們已經新增了專門用來建立多種大小格線的新配置:CellSpanningLayout

這個範例定義資料來源,以及使用 CellSpanningLayoutListViewitemInfogroupInfo 方法。ListView 中每個項目的大小都是 250 x 250 像素,除了第一個項目以外,它的高度為 510 像素。


(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 中群組項目。)

附註  如果您透過在標頭中包含連結或按鈕,讓標頭在適用於 JavaScript 1.0 的 Windows Library 中變成可叫用,則當您切換到適用於 JavaScript 2.0 的 Windows Library 時,使用者將無法使用鍵盤叫用該標頭。 若要修正這個問題,請處理 ongroupheaderinvoked 事件並使用它來執行標頭動作,而不要使用按鈕或連結。

配置介面的更新

ListView 現在有一組新的配置介面,更易於建立您自己的自訂配置:ILayout2ISiteLayout2。在您實作這些介面時,可以使用標準 CSS 配置做為實作的一部分。

ListLayout 和 GridLayout 的更新

我們已經更新 ListLayoutGridLayout 來改進它們的整體效能,特別是移動瀏覽效能。您不需要變更任何程式碼就可以充分利用這些改進功能。

其他 WinJS 更新

繫結和 WinJS.Binding.Template 更新

適用於 JavaScript 2.0 的 Windows Library 會使用更有效率的新系統來處理 Template 物件,大幅改善了效能。使用新系統時,資料繫結和控制項具現化的程序會更流暢地平行處理,而不像在適用於 JavaScript 1.0 的 Windows Library 中一樣序列處理。如果您的程式碼倚賴舊版序列處理行為,建議您變更程式碼以利用更快速的範本處理。不過,如果您無法變更程式碼,則可以使用 disableOptimizedProcessing 屬性來還原舊行為。

Dispose API

「處置模型」是新的模式,可以讓元素和控制項在其存留期結束時釋出資源,以防止記憶體流失。 元素或控制項可以選擇性地實作它。適用於 JavaScript 2.0 的 Windows Library 控制項如果有可釋放的資源,就會立即實作這個 API。

若要利用處置模型,請在已不需要該控制項的時候 (例如,離開瀏覽頁面或應用程式關閉時),呼叫控制項的 dispose 方法。

 

 

顯示:
© 2014 Microsoft