コントロール (HTML と JavaScript)

Windows 8.1 の新しい HTML コントロールと JavaScript コントロールを使って、カスタム コマンドやナビゲーション サポートの強化などの新しい機能を Windows ストア アプリに追加します。 既にあるコントロールは使いやすく更新され、ドラッグ アンド ドロップのサポートなどの機能が追加されています。 これらの新しいコントロールやコントロールの更新のおかげで、すべての機能を備えたアプリをこれまでになく簡単に作成できます。

Windows 8.1 と JavaScript 2.0 用 Windows ライブラリには、次の新しいコントロールと機能が導入されています。

  • AppBarCommand
  • BackButton
  • Hub
  • ItemContainer
  • NavBar
  • Repeater
  • WebView

Windows 8.1 と JavaScript 2.0 用 Windows ライブラリには、次の既にあるコントロール用に更新が導入されています。

  • ListView でのドラッグ アンド ドロップのサポート
  • ListView での項目の並べ替え
  • ListView の新しいレイアウト: CellSpanningLayout
  • ListView のその他の更新
  • JavaScript 用 Windows ライブラリのその他の更新

JavaScript 2.0 用 Windows ライブラリの使用

新しい Microsoft Visual Studio 2013 プロジェクトには、自動的に JavaScript 2.0 用 Windows ライブラリが含まれます。Windows 8 で作られたプロジェクトで JavaScript 2.0 用 Windows ライブラリを使うには、既にある JavaScript 1 用 Windows ライブラリ参照を...

    <!-- 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 ライブラリへの参照で置き換えます。

    <!-- 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 では、content という新しい種類の AppBarCommand を使って、JavaScript を使った Windows ストア アプリでカスタム アプリ バー コマンドを作成できます。

この機能では、commands のレイアウトにカスタム コンテンツを配置できるようにすることで、カスタム コンテンツを使ってアプリ バーを作成するプロセスが簡素化されます。キーボード操作、コマンドの配置、コマンドの動的な表示と非表示のためのアニメーションを含むカスタム コンテンツを持つアプリ バー コマンドの完全な組み込みサポートを利用できます。

コンテンツの種類 AppBarCommand は、commands のレイアウトに配置すると、既定のアプリ バー コマンドと同じ機能の多くをサポートします。

  • 既定のアプリ バー コマンドとカスタム AppBarCommand 間で、キーボード操作 (Tab キー、方向キー、Home キー、End キー) が有効になります。

  • アプリ バーの拡大縮小は、新しいコンテンツの種類 AppBarCommand に対しても正しく機能します。コマンドのテキスト ラベルは、アプリが小さいサイズに変更されると動的に破棄されます。

BackButton

Windows 8.1 と JavaScript 2.0 用 Windows ライブラリでは、より多くのナビゲーション サポートが、アプリで使用できるコントロールの形式でプラットフォームに追加されます。これらのコントロールの 1 つが、BackButton です。

BackButton を使うと、戻る移動を簡単にアプリに追加することができます。BackButton コントロールは簡単に作成できます。

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

新しい BackButton コントロール

BackButton は、自動的にナビゲーション スタックを確認し、ユーザーがページを戻ることができるかどうか判断します。ページを戻ることができない場合、ボタンは無効になります。ユーザーがボタンをクリックするか、キーボード ショートカット (Alt + ←や BrowserBack キーなど) を使うと、自動的に WinJS.Navigation.back を呼び出してページを戻ります。コードは一切記述する必要がありません。

Hub

[HTML Hub コントロールのサンプルを今すぐ入手する]

Windows 8.1 と JavaScript 2.0 用 Windows ライブラリには、より一貫したナビゲーション エクスペリエンスを提供するため、Hub コントロールが追加されています。

多くの Windows ストア アプリは、ナビゲーションの階層システムであるハブ ナビゲーション パターンを使っています。このパターンは、コンテンツのコレクションが大きいアプリや、ユーザーがコンテンツのさまざまなセクションを探索するアプリに最適です。

ハブ設計の本質は、コンテンツをさまざまなセクションとさまざまな詳細レベルに分けることです。 ハブ ページは、ユーザーのアプリへの入り口です。コンテンツが横方向または縦方向にスクロールできるビューに表示され、新しい情報や入手可能な項目がひとめでわかります。 ハブはさまざまなコンテンツのカテゴリで構成され、それぞれがアプリのセクション ページにマップします。各セクションは、コンテンツや機能でいっぱいにしてください。ハブで多様なビジュアルを提供し、ユーザーの興味を引きつけて、アプリのさまざまな部分に引き込みます。

ハブ ページ

 

Windows 8.1 では、Hub コントロールを使うと、簡単にハブ ページを作成できます。Hub ページを使ったアプリを直ちに作成する場合は、Visual Studio 2013 のハブ アプリ テンプレートを使います。

ハブの作成

ハブを作成するには、Hub コントロールを追加し、ハブに含まれるセクションごとに HubSection オブジェクトを追加します。各 HubSection には、JavaScript 用 Windows ライブラリのその他のコントロールを含めて、あらゆる種類のコンテンツを含めることができます。セクション ヘッダーを指定するには、header プロパティを使います。セクション ヘッダーは、静的にすることも対話型にすることもできます。対話型ヘッダーには山かっこが表示されます。この山かっこはユーザーが操作するときに非表示にして、イベントを生成することができます。

この例では、次の 3 つのセクションを持つ 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>

このコードによって、次のページが作られます。

ハブ ページ

 

2 番目の見出しをクリックすると、アプリはセクション ページに移動します。

セクション ページ

 

ナビゲーションを実行するコードを次に示します。

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

SemanticZoom コントロールと Hub コントロールを一緒に使うこともできます。その他の例については、HTML Hub コントロールのサンプルに関するページをご覧ください。

ItemContainer

[HTML ItemContainer コントロールのサンプルを今すぐ入手する]

新しい ItemContainer コントロールを使うと、スワイプ、ドラッグ アンド ドロップ、ホバー機能を提供する対話要素を簡単に作成できます。ItemContainer 内にコンテンツを配置するだけです。ItemContainer には、標準の HTML 要素や、その他の WinJS コントロールを含めることができます。

ItemContainer には柔軟性があり、リッチなチェック ボックスのグループ、ナビゲーション ボタン、ショッピング カートの表現を作るなど、多くの用途に適しています。

ナビゲーション バーの ItemContainer オブジェクト

 

項目を表示する必要があるが、ListView コントロールのすべての機能は必要ない場合は、ItemContainer を使います。

ItemContainer の使用

この例では、2 つの 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>

2 つの ItemContainer オブジェクト

 

ItemContainerRepeater コントロールと共に使って、List から項目を生成することもできます。そのためには、ItemContainerTemplate コントロール内に配置するだけです。

<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 に設定します。

[HTML NavBar コントロールのサンプルを今すぐ入手する]

Windows 8.1 と JavaScript 2.0 用 Windows ライブラリには、一貫した予測可能なナビゲーション エクスペリエンスを提供するため、WinJS.UI.NavBar という新しいコントロールが導入されています。

データ ソースから生成されたナビゲーション項目を含む NavBar

 

NavBar は、ナビゲーション コマンドに特化された AppBar のようなものです (事実、NavBarAppBar のサブクラスです)。また、リンクのシンプルな一覧や、カテゴリに整理された複数レベルのリンクを含めることができます。エントリのハード コーディング、プログラムによる更新、またはデータ バインディングを使って、NavBar を設定できます。

NavBar は、ユーザーが必要とする場合はアプリ画面の上部に表示されます。ユーザーは、端のスワイプを実行するか、Windows ロゴ キーを押しながら Z キーを押すか、右クリックすることにより、NavBar を呼び出します。

NavBar は、縦長レイアウトと分割ナビゲーション項目 (下位のナビゲーション オプションがあるナビゲーション項目) もサポートしています。NavBar は詳しくカスタマイズできます。NavBar とコンテンツのほとんどの部分は、カスケード スタイル シート (CSS) を使ってスタイルを指定し、カスタムのナビゲーション項目を作成することもできます。

NavBar には次の 3 つのコンポーネントがあります。

  • NavBar 自体。

  • ナビゲーション項目 (NavBarCommand オブジェクト) が含まれ、改ページ調整とパン/スクロールの両方をサポートする NavBarContainer オブジェクト。単一の NavBar に 1 つまたは複数の NavBarContainer オブジェクトを含めることができます。ナビゲーション オプションのグループを定義するには、NavBarContainer オブジェクトを使います。

  • 1 つ以上の NavBarCommand オブジェクト。 これらは、移動するためにユーザーがクリックするものです。

ナビゲーションを有効にするには、NavBarCommand オブジェクトの location プロパティを設定できます。ユーザーがコマンドをクリックすると、WinJS.Navigation.navigated イベントが発生します。 このイベントを使って、指定された場所に移動します。

または、NavBar 上の oninvoked イベントに登録し、イベント ハンドラーを使ってナビゲーション操作を行うことができます。

この例では、2 つのナビゲーション項目を含む単純な 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 ページを初期化し、子 NavBarCommand オブジェクトが含まれている Flyout を表示する splittoggle イベント ハンドラーを追加します。

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

次の例は、NavBar オブジェクトと NavBarContainer オブジェクトを作成する 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 は、テンプレートを使ってデータ セットから HTML マークアップを生成する、使いやすい WinJS のコントロールです。このテンプレートには、ほとんどの HTML マークアップと WinJS のコントロールを含めることができます。Repeater コントロール内に Repeater コントロールを入れ子にすることもできます。

カスタム リストやユーザー設定の表を生成するには、Repeater を使います。Repeater によって作成された天気予報の例を次に示します。

リピーター コントロール

 

RepeaterListView コントロールの代替機能ではありません。Repeater は 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 では、Web ベースのコンテンツをホストするために iframe 要素を使うことができますが、コンテンツ分離機能やナビゲーション機能はそれほど用意されていません。Windows 8.1 には、WebView という新しいコントロールが導入されており、これを使うことで、アプリでの Web ベースのコンテンツのホストが大幅に簡単になります。

iframe を使った Web ベースのコンテンツの表示に対する WebView での強化点をいくつか次に示します。

  • HTML5 のサポート

    WebView でホストされるページでは、ほとんどの HTML5 機能にアクセスできます。ただし、WebView は、IndexedDBHTML5 アプリのキャッシュ地理位置情報 API、または Clipboard API にアクセスできません。

  • ナビゲーション サポートの強化

    WebView には独自の履歴スタックがあり、ページを戻ったり進んだり、現在のページをもう一度読み込んだりするための複数のメソッドが提供されます。

  • フレーム内で機能しないサイトのサポート

    WebView は、frame 要素または iframe 要素内で機能しないサイトを表示できます。

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="https://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);
    
  • ms-appdata:// プロトコルを指定した navigate メソッドを使って、アプリの状態のフォルダーに格納されている HTML コンテンツを読み込みます。

     document.getElementById("webview").navigate(
        "ms-appdata:///local/NavigateToState/simple_example.html");
    
  • HTML ベースのファイル形式については、必要に応じて相対参照をストリーミングすると便利な場合があります。たとえば、WebView コントロールでネイティブにレンダリングできない、暗号化された HTML コンテンツなどです。buildLocalStreamUri メソッドと navigateToLocalStreamUri メソッドを使って、ストリームからコンテンツを表示します (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 ライブラリでは、ListView にドラッグ アンド ドロップ操作のサポートが追加されています。この新しいサポートは、HTML 5 のドラッグ アンド ドロップ機能と互換性があります。2 つの 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 で項目を簡単に並べ替えることができるようになります。itemsReorderabletrue に設定するだけで、ユーザーが 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 ライブラリでは、ListView に複数のサイズの項目を含める場合は、GridLayout を使いました。JavaScript 2.0 用 Windows ライブラリでは、複数サイズのグリッド作成のための専用の新しいレイアウト (CellSpanningLayout) が追加されています。

この例では、データ ソースと、CellSpanningLayout を使う ListView 用の groupInfo メソッドと itemInfo メソッドが定義されます。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 内の項目をグループ化する方法」をご覧ください)。

  JavaScript 1.0 用 Windows ライブラリで、ヘッダーにリンクまたはボタンを含めることでヘッダーを呼び出し可能にした場合、JavaScript 2.0 用 Windows ライブラリに切り替えたときに、ユーザーはキーボードを使ってヘッダーを呼び出すことができなくなります。 この問題を解決するには、ongroupheaderinvoked イベントを処理し、ボタンやリンクを使う代わりにこのイベントを使ってヘッダーの操作を行います。

レイアウトのインターフェイスの更新

ListView には、独自のカスタム レイアウトを簡単に作成できるようにする一連の新しいレイアウト インターフェイスが用意されました。それらのインターフェイスは、ILayout2ISiteLayout2 です。それらのインターフェイスを実装するときは、実装の一部として CSS の標準的なレイアウトを使うことができます。

ListLayout と GridLayout の更新

全体のパフォーマンス (特にパンのパフォーマンス) を向上させるために、ListLayoutGridLayout が更新されました。これらの強化点を利用するために、コードを変更する必要は一切ありません。

WinJS のその他の更新

Binding と WinJS.Binding.Template の更新

JavaScript 2.0 用 Windows ライブラリでは、Template オブジェクトを処理するための新しい効率的なシステムが使われます。これにより、大幅にパフォーマンスが向上します。新しいシステムでは、データ バインディングとコントロールのインスタンス化は、JavaScript 1.0 用 Windows ライブラリのように系列ではなく、より柔軟な並列プロセスで発生します。コードが従来のシリアル処理動作に依存している場合は、コードを変更し、より高速なテンプレート処理を利用することをお勧めします。ただし、コードを変更できない場合は、disableOptimizedProcessing プロパティを使って前の動作を復元することができます。

Dispose API

破棄モデルは、メモリ リークが発生しないように要素とコントロールが有効期間の終了時にリソースを解放できるようにする新しいパターンです。 要素またはコントロールは、オプションでこのモデルを実装できます。解放するリソースを持っている JavaScript 2.0 用 Windows ライブラリのコントロールは、この API を実装するようになりました。

破棄モデルを利用するには、ページから移動するときや、アプリをシャットダウンするときなど、コントロールが不要になったときに、コントロールの dispose メソッドを呼び出します。