Share via


Controles (HTML con JavaScript)

Agrega nuevas características a tu aplicación de la Tienda Windows, como comandos personalizados y compatibilidad con la navegación mejorada, con los nuevos controles HTML y JavaScript en Windows 8.1. Las actualizaciones de los controles existentes facilitan su uso y agregan más características, como arrastrar y colocar. Estos nuevos controles y actualizaciones de controles hacen que sea más fácil que nunca crear una aplicación completa.

Nuevos controles y actualizaciones de controles

Windows 8.1 y la biblioteca de Windows para JavaScript 2.0 presentan estos nuevos controles y características:

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

Windows 8.1 y la biblioteca de Windows para JavaScript 2.0 incluyen actualizaciones de estos controles existentes:

  • Compatibilidad con arrastrar y colocar para ListView
  • Reordenar elementos en ListView
  • Nuevo diseño de ListView: CellSpanningLayout
  • Otras actualizaciones de ListView
  • Otras actualizaciones de la biblioteca de Windows para JavaScript

Uso de la biblioteca de Windows para JavaScript 2.0

Los nuevos proyectos de Microsoft Visual Studio 2013 incluyen automáticamente la biblioteca de Windows para JavaScript 2.0. Para usarla en un proyecto creado con Windows 8, reemplaza tus referencias actuales a la biblioteca de Windows para 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>

...con referencias a la biblioteca de Windows para 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 puede actualizar automáticamente tu proyecto, o bien puedes realizar manualmente estas actualizaciones adicionales:

  • Agrega a tu proyecto una referencia a la biblioteca de Windows 8.1 para JavaScript.

  • En el manifiesto de aplicación, actualiza los valores de OSMinVersion y OSMaxVersionTested a 6.3.0:

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

AppBarCommand

[Obtén la muestra del control HTML AppBar ahora.]

En Windows 8.1, puedes crear comandos de la barra de la aplicación personalizados en aplicaciones de la Tienda Windows con JavaScript mediante un nuevo tipo de AppBarCommand denominado content.

Esta característica simplifica el proceso de crear una barra de la aplicación con contenido personalizado, ya que te permite incluir contenido personalizado en el diseño de commands. Puedes aprovechar la compatibilidad integrada y completa de los comandos de la barra de la aplicación con el contenido personalizado, incluido el uso del teclado, la alineación de comandos y las animaciones para mostrar y ocultar comandos dinámicamente.

Cuando se incluye en el diseño de commands, el tipo de contenido AppBarCommand admite muchas de las mismas características que los comandos predeterminados de la barra de la aplicación.

  • Se permite el uso del teclado (tabulador, flechas, teclas Inicio y Fin) entre los comandos predeterminados de la barra de la aplicación y el AppBarCommand personalizado.

  • La escala de la barra de la aplicación funciona correctamente con el nuevo tipo de contenido AppBarCommand. Las etiquetas de texto de los comandos se colocan dinámicamente cuando se cambia el tamaño de la aplicación para hacerla más pequeña.

BackButton

Windows 8.1 y la biblioteca de Windows para JavaScript 2.0 agregan a la plataforma más compatibilidad con la navegación, en forma de controles para tus aplicaciones. Uno de estos controles es BackButton.

BackButton te proporciona una forma sencilla de agregar navegación regresiva a tu aplicación. Es muy sencillo crear un control BackButton.

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

El nuevo control BackButton

BackButton comprueba automáticamente la pila de navegación para determinar si el usuario puede navegar hacia atrás. Si no hay ningún contenido al que se pueda navegar hacia atrás, el botón se desactiva a sí mismo. Cuando el usuario hace clic en el botón o usa métodos abreviados de teclado (como Alt+izquierda o las teclas BrowserBack), llama automáticamente a la función WinJS.Navigation.back para navegar hacia atrás. No es necesario que escribas ningún código.

Hub

[Obtén la muestra del control HTML Hub ahora.]

Para poder proporcionar una experiencia de navegación más coherente, Windows 8.1 y la biblioteca de Windows para JavaScript 2.0 agregan el control Hub.

Muchas aplicaciones de la Tienda Windows usan el diseño de navegación de concentrador, un sistema de navegación jerárquico. Este diseño está indicado para aplicaciones con grandes colecciones de contenido o muchas secciones de contenido diferentes que un usuario puede explorar.

La esencia del diseño de concentrador es la separación del contenido en distintas secciones y niveles de detalle. Las páginas de concentrador son el punto de acceso del usuario a la aplicación. Aquí, el contenido se muestra en una vista panorámica horizontal o vertical que permite a los usuarios obtener una vista rápida de lo que es nuevo y está disponible. El concentrador consta de distintas categorías de contenido, cada una de las cuales se asigna a las páginas de sección de la aplicación. De cada sección debe emerger contenido o funcionalidades. El concentrador debe ofrecer una amplia variedad visual, atraer a los usuarios y llevarlos a distintas partes de la aplicación.

Una página de concentrador

 

Con Windows 8.1, el control Hub facilita la creación de una página de concentrador. Para empezar a crear rápidamente una aplicación con una página Hub, usa la plantilla Hub App de Visual Studio 2013.

Creación de un concentrador

Para crear un concentrador, debes agregar un control Hub y un objeto HubSection para cada sección que contenga el concentrador. Cada HubSection puede contener cualquier tipo de contenido, incluidos otros controles de la biblioteca de Windows para JavaScript. Usa la propiedad header para especificar el encabezado de sección. Los encabezados de sección pueden ser estáticos o interactivos. Los encabezados interactivos muestran comillas angulares que pueden ocultarse y generar eventos cuando el usuario interactúa con ellos.

Este ejemplo define un control Hub que tiene tres secciones.

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

Ese código crea esta página.

Una página de concentrador

 

Cuando haces clic en el segundo encabezado, la aplicación va a una página de sección.

Una página de sección

 

Este es el código que realiza la navegación.

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

Puedes usar incluso el control Hub con el control SemanticZoom. Para ver más ejemplos de esto y obtener información adicional, consulta la muestra del control HTML Hub.

ItemContainer

[Obtén la muestra del control HTML ItemContainer.]

El nuevo control ItemContainer facilita la creación de elementos interactivos que proporcionan funcionalidad de deslizar rápidamente, arrastrar y colocar y mantener el mouse. Simplemente debes colocar el contenido dentro de ItemContainer. ItemContainer puede contener elementos HTML estándar e incluso otros controles de WinJS.

ItemContainer es flexible, lo que lo convierte en idóneo para muchos usos, como crear grupos de casillas enriquecidos, botones de navegación y representaciones de carros de la compra.

Objetos ItemContainer en una barra de navegación

 

Usa un ItemContainer cuando quieras mostrar elementos pero no necesites todas las características del control ListView.

Uso de ItemContainer

En este ejemplo se crean dos objetos ItemContainer y se establece su propiedad tapBehavior en toggleSelect para que puedan seleccionarse.

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

Dos objetos ItemContainer

 

También puedes usar un ItemContainer con un Repeater para generar elementos de una List: simplemente debes colocar ItemContainer dentro del control 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>

Este ejemplo define el origen de datos.

(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

        });
})();

Objetos ItemContainer generados por un Repeater

 

Los elementos pueden seleccionarse de forma predeterminada. Para deshabilitar la selección, establece la propiedad selectionDisabled del control ItemContainer en true.

[Obtén la muestra del control HTML NavBar ahora.]

Windows 8.1 y la biblioteca de Windows para JavaScript 2.0 presentan un control nuevo que te ayudará a ofrecer una experiencia de navegación coherente y predecible: el control WinJS.UI.NavBar.

NavBar que contiene elementos de navegación generados desde un origen de datos

 

La NavBar es como una AppBar dedicada a comandos de navegación. (De hecho, la NavBar es una subclase de la AppBar). Puede contener una lista sencilla de vínculos, además de varios niveles de vínculos organizados en categorías. Puedes rellenar la NavBar con entradas codificadas de forma rígida, actualizarla mediante programación o utilizar el enlace de datos.

La NavBar aparece en la parte superior de la ventana de la aplicación cuando el usuario la necesita. Para invocar a la NavBar, el usuario puede deslizar rápidamente el borde, presionar la tecla de logotipo de Windows + Z o hacer clic con el botón secundario.

La NavBar también admite diseños verticales y elementos de navegación dividida (elementos de navegación con opciones de navegación secundarias). NavBar se puede personalizar en gran medida: puedes usar hojas de estilos en cascada (CSS) para aplicar estilos a prácticamente cualquier aspecto de NavBar y de su contenido, y también puedes crear elementos de navegación personalizados.

Creación de un control NavBar

La NavBar tiene tres componentes:

  • La propia NavBar.

  • Un objeto NavBarContainer, que contiene los elementos de navegación (objetos NavBarCommand) y admite tanto la paginación como el movimiento panorámico y el desplazamiento. Puedes tener uno o más objetos NavBarContainer en una misma NavBar. Los objetos NavBarContainer se usan para definir grupos de opciones de navegación.

  • Uno o más objetos NavBarCommand. Son los objetos en los que el usuario hace clic para navegar.

Para habilitar la navegación, puedes establecer la propiedad location del objeto NavBarCommand. Cuando el usuario hace clic en el comando, se activa el evento WinJS.Navigation.navigated. Usa este evento para navegar a la ubicación especificada.

Como alternativa, puedes registrarte en el evento oninvoked de NavBar y usar el controlador de eventos para realizar la acción de navegación.

Este ejemplo muestra un control NavBar sencillo que contiene dos elementos de navegación.

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

Este es el aspecto de NavBar.

NavBar

 

Puedes crear un NavBarCommand que contenga objetos NavBarCommand secundarios. Para ello, debes establecer la propiedad splitButton del objeto NavBarCommand primario en true y usar el evento splittoggle para mostrar un Flyout que contenga los objetos NavBarCommand secundarios. Aquí tienes código de ejemplo de la primera parte.

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

El siguiente ejemplo muestra el código que inicializa la página HTML y agrega el controlador de eventos splittoggle, que muestra el Flyout que contiene los objetos NavBarCommand secundarios.

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

(Para ver el código completo, consulta la muestra del control HTML NavBar.)

Este es el aspecto de NavBar con el botón de expansión abierto:

Un NavBarCommand dividido

 

Puedes enlazar un NavBarContainer a un origen de datos. Para ello, crea un control List que contenga datos que describan los comandos de navegación y úsalos para establecer la propiedad data del objeto NavBarContainer. Este ejemplo define los datos que usa el 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();
        }
    });
})();

El siguiente ejemplo muestra el HTML que crea los objetos NavBar y NavBarContainer.

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

(Para ver el código completo, consulta la muestra del control HTML NavBar.)

Cuando ejecutes el código, se creará su NavBar.

NavBar que contiene elementos de navegación generados desde un origen de datos

 

Aunque no se muestra aquí, también puedes usar un objeto WinJS.Binding.Template con un origen de datos para generar elementos de la barra de navegación.

Repeater

[Obtén la muestra del control HTML Repeater ahora.]

Repeater es un control de WinJS sencillo y fácil de usar que utiliza una plantilla para generar formato HTML a partir de un conjunto de datos. La plantilla puede contener prácticamente cualquier formato HTML y cualquier control de WinJS. Incluso puedes anidar controles Repeater dentro de controles Repeater.

Usa Repeater para generar listas y tablas personalizadas. Aquí tienes un ejemplo de una previsión meteorológica creada por un Repeater.

Control Repeater

 

Repeater no es un sustituto del control ListView. Es más flexible pero no ofrece algunas de las características avanzadas de ListView, como el control sobre la carga de los elementos de datos.

Uso de Repeater

Un Repeater genera sus datos a partir de List. Este ejemplo crea un objeto List que contiene unos cuantos elementos sencillos.

(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

        });
})();

Para especificar el marcado generado por Repeater, debes definir una template. Puedes crear una plantilla en el marcado o usar una función de plantillas. En este ejemplo se crea una plantilla mediante marcado. Enlaza mediante datos el campo de título del origen de datos con el contenido del texto de un elemento li.

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

El siguiente ejemplo crea el Repeater en sí mismo.

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

Cuando ejecutas la aplicación, Repeater genera un elemento li para cada elemento de la lista de datos.

Una lista generada por el control Repeater

 

WebView con SmartScreen

[Obtén la muestra del control HTML WebView ahora.]

En Windows 8, podías usar el elemento iframe para incluir contenido web pero no proporcionaba mucha funcionalidad de navegación o aislamiento de contenido. Windows 8.1 presenta el nuevo control WebView, que hace que sea mucho más sencillo incluir contenido web en las aplicaciones.

Estas son algunas de las mejorar que ofrece WebView con respecto al uso de iframe para mostrar contenido web:

  • Compatibilidad con HTML5

    Las páginas incluidas en un control WebView pueden acceder a la mayoría de la funcionalidad HTML5. (Sin embargo, WebView no puede acceder a la caché de la aplicación HTML5 IndexedDB, a la Geolocation API ni a Clipboard API).

  • Compatibilidad con la navegación mejorada

    WebView tiene su propia pila de historial independiente y ofrece varios métodos para navegar hacia delante y hacia atrás, y para recargar la página actual.

  • Compatibilidad con sitios que no funcionan dentro de marcos

    WebView puede mostrar sitios que no funcionan dentro de elementos frame o iframe.

Uso de WebView para cargar contenido

Para crear un control WebView, puedes crear un elemento x-ms-webview.

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

Puedes usar WebView de varias formas para cargar contenido:

  • Usa la propiedad src del control WebView, el método navigate o el método navigateWithHttpRequestMessage para navegar a un URI. Este ejemplo usa la propiedad src para navegar a un URI.

    <x-ms-webview id="webview" src="https://go.microsoft.com/fwlink/p/?LinkID=294155" 
        style="width: 400px; height: 400px;">
    </x-ms-webview>
    
  • Usa el método navigateToString para cargar una cadena arbitraria de 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);
    
  • Puedes usar el método navigate con el protocolo ms-appdata:// para cargar contenido HTML almacenado en las carpetas de estado de la aplicación.

     document.getElementById("webview").navigate(
        "ms-appdata:///local/NavigateToState/simple_example.html");
    
  • En formatos de archivos basados en HTML, a veces puede ser útil transmitir en secuencias las referencias relativas a medida que se necesitan, por ejemplo, como ocurre con el contenido HTML cifrado que no puede representarse de forma nativa mediante el control WebView. Usa los métodos buildLocalStreamUri y navigateToLocalStreamUri para mostrar el contenido de una secuencia. (También debes implementar un objeto de Windows en tiempo de ejecución personalizado que use la interfaz IUriToStreamResolver.)

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

Para ver ejemplos completos, consulta la muestra del control HTML WebView.

Compatibilidad con arrastrar y colocar para ListView

[Obtén la muestra para arrastrar y colocar y reordenar un control HTML ListView ahora.]

Con la biblioteca de Windows para JavaScript 2.0, ListView agrega compatibilidad con las operaciones de arrastrar y colocar. Esta nueva compatibilidad admite la funcionalidad de arrastrar y colocar de HTML 5. Puedes arrastrar y colocar entre dos controles ListView, entre un ItemContainer y un ListView, y entre cualquier elemento HTML y ListView. Puedes permitir que el usuario coloque elementos en una ubicación específica de ListView o puedes controlar dónde se insertan los elementos colocados, por ejemplo, reordenando los elementos del control ListView después de haber agregado un nuevo elemento.

Arrastrar un elemento de ListView

Para habilitar la funcionalidad de arrastrar un elemento de ListView a un destino de colocación HTML 5, debes hacer lo siguiente:

  1. Establece la propiedad itemsDraggable de ListView en true.

  2. Administra el evento itemdragstart del control ListView. En tu controlador de eventos, obtén un objeto dataTransfer de la propiedad detail del objeto de evento. Usa el método setData del objeto dataTransfer para especificar cómo se transferirán los datos y qué datos hay que transferir.

  3. Administra el evento dragover del destino de colocación. En tu controlador de eventos, usa el método preventDefault del objeto event para indicar al sistema que aceptas la colocación. De lo contrario, el destino de colocación no aceptará la operación de colocación.

  4. Administra el evento drop del destino de colocación. En tu controlador de eventos, obtén un objeto dataTransfer de la propiedad detail del objeto de evento. Usa la propiedad getData del objeto dataTransfer para recuperar los datos que se están transfiriendo. Usa estos datos para actualizar el destino de colocación. Procura no aceptar que se puedan arrastrar elementos intrínsecamente arrastrables de tu aplicación, como texto seleccionado y elementos img.

Aquí tienes un conjunto de ejemplos que muestran cómo habilitar la funcionalidad de arrastrar un elemento desde ListView. El primer ejemplo define el formato 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>

Esta es la hoja CSS de la operación de arrastrar y colocar.

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

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

El siguiente ejemplo muestra el código que habilita la funcionalidad de arrastrar y colocar.

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

        }
    });

})();

Para ver el código completo, consulta la muestra para arrastrar y colocar y reordenar un control HTML ListView.

Colocar un elemento en ListView

Para colocar un elemento en una ubicación específica de ListView, debes hacer lo siguiente:

  1. Establece la propiedad draggable del elemento HTML (el origen de arrastre) en true.

  2. Administra el evento dragstart del destino de colocación. En tu controlador de eventos, obtén un objeto dataTransfer del objeto de evento. Usa el método setData del objeto dataTransfer para especificar cómo se transferirán los datos y qué datos hay que transferir.

  3. Administra el evento itemdragenter del control ListView. En tu controlador de eventos, usa el método preventDefault del objeto event para indicar al sistema que aceptas la colocación. De lo contrario, el resultado de la operación de arrastre será impredecible.

  4. Administra el evento itemdragdrop del control ListView. En tu controlador de eventos, obtén un objeto dataTransfer de la propiedad detail del objeto de evento. Usa la propiedad getData del objeto dataTransfer para recuperar los datos que se están transfiriendo. Usa estos datos para actualizar ListView.

Aquí tienes un conjunto de ejemplos que muestran cómo habilitar la colocación de un elemento en ListView. El primer ejemplo define el formato 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>

El siguiente ejemplo muestra el código que habilita la funcionalidad de arrastrar y colocar.

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

Para ver el código completo, consulta la muestra para arrastrar y colocar y reordenar un control HTML ListView.

Reordenar elementos en ListView

Poder reordenar el contenido hace que los usuarios sientan que controlan la situación. La nueva propiedad itemsReorderable permite que el usuario pueda cambiar fácilmente el orden de los elementos de ListView. Solo tienes que establecer itemsReorderable en true para permitir que los usuarios arrastren elementos dentro de ListView; no se necesita ningún otro código.

Nota  Para habilitar completamente la reordenación de elementos en un control ListView agrupado, también debes responder al evento itemdragdrop e insertar el elemento de forma adecuada en la ubicación correcta.

Nota  Para que funcione la reordenación, tu origen de datos debe admitir la reordenación.

Este ejemplo crea un control ListView que admite la reordenación de elementos.

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

El siguiente ejemplo define el origen de datos que usa 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
        })

})();

Cuando se ejecuta el código, el usuario puede reordenar los elementos de ListView arrastrándolos.

Reordenación de ListView

Nuevo diseño de ListView: CellSpanningLayout

Con la biblioteca de Windows para JavaScript 1.0, si querías que un control ListView pudiese contener elementos de varios tamaños, usabas un GridLayout. En la biblioteca de Windows para JavaScript 2.0, hemos agregado un nuevo diseño específico para crear cuadrículas de varios tamaños: CellSpanningLayout.

Este ejemplo define el origen de datos y los métodos itemInfo y groupInfo para un control ListView que usa un CellSpanningLayout. Cada elemento de ListView tiene un tamaño de 250 píxeles por 250 píxeles, excepto el primer elemento, que tiene 510 píxeles de alto.

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


})();

El siguiente ejemplo muestra el HTML para crear ListView y WinJS.Binding.Template.

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

Este es el aspecto de ListView.

Un control ListView que usa CellSpanningLayout

Otras actualizaciones de ListView

Windows 8.1 incluye incluso más mejoras del control ListView.

Mejor accesibilidad en los encabezados

Los encabezados de un control ListView agrupado ahora admiten la navegación con el teclado e interacción entre el teclado y el mouse. No es necesario que cambies el código para obtener estas nuevas características.

(Para obtener más información sobre la creación de grupos, consulta el tema sobre cómo agrupar elementos en un control ListView.)

Nota  Si incluiste un vínculo o un botón en el encabezado para que se pudiera invocar en la biblioteca de Windows para JavaScript 1.0, los usuarios no podrán invocar el encabezado con el teclado cuando cambies a la biblioteca de Windows para JavaScript 2.0. Para corregir este problema, administra el evento ongroupheaderinvoked y úsalo para realizar la acción de encabezado en lugar de usar un botón o vínculo.

Actualizaciones en la interfaz de diseño

ListView tiene ahora un conjunto de interfaces de diseño que hacen que sea más sencillo crear tu propio diseño personalizado: ILayout2 y ISiteLayout2. Cuando implementes estas interfaces, puedes usar diseños CSS estándar como parte de tu implementación.

Actualizaciones de ListLayout y GridLayout

Hemos actualizado ListLayout y GridLayout para mejorar su rendimiento global, especialmente el rendimiento del movimiento panorámico. No es necesario que cambies el código para aprovechar estas mejoras.

Otras actualizaciones de WinJS

Actualizaciones de Binding y WinJS.Binding.Template

La biblioteca de Windows para JavaScript 2.0 usa un sistema nuevo y más eficiente para procesar objetos Template que mejora significativamente el rendimiento. Con el nuevo sistema, el enlace de datos y la creación de instancias de controles se producen en un proceso paralelo más fluido en lugar de hacerlo en serie, como sucedía en la biblioteca de Windows para JavaScript 1.0. Si tu código depende del comportamiento de procesamiento en serie heredado, te recomendamos que realices cambios en el código para aprovechar la mayor velocidad en el procesamiento de plantillas. Sin embargo, puedes usar la propiedad disableOptimizedProcessing para restaurar el comportamiento anterior si no puedes cambiar el código.

La API de eliminación

El modelo de eliminación es un nuevo diseño que permite que los elementos y controles liberen recursos al final de su vigencia para evitar pérdidas de memoria. Un elemento o control puede implementarlo de manera opcional. Los controles de la biblioteca de Windows para JavaScript 2.0 que tengan recursos para liberar ahora implementan esta API.

Para aprovechar el modelo de eliminación, llama al método dispose del control cuando el control ya no sea necesario, por ejemplo, si estás navegando fuera de una página o si se cierra la aplicación.