Статьи

31 день Windows 8 для HTML5 | День № 13 Навигация

Эта статья является Днем № 13 из серии под названием 31 Дней Windows 8 . Каждая из статей этой серии будет опубликована как для HTML5 / JS, так и для XAML / C # . Вы можете найти дополнительные ресурсы, загрузки и исходный код на нашем сайте .

advertisementsample4


Последние несколько дней мы потратили на то, чтобы обновить систему с помощью информации, чтобы наши пользователи знали, что происходит. Фактически, в первые 12 дней этой серии мы потратили очень мало времени на обсуждение того, как выполнить одно из самых распространенных действий, с которыми мы сталкиваемся при разработке под Windows 8: навигация. Теперь вы можете сидеть там и говорить, привязывать теги, строки запросов и гимнастику JavaScript, верно? Возможно, вы даже подумали: «Я могу пропустить это, это web 101», и хотя это несколько верно, вам нужно понять, куда вписывается WinJS и что делать, когда ваше приложение закрывается.

Я почти уверен, что мы все сделали какую-то навигацию на наших сайтах, но давайте немного определимся, как сегодняшние веб-практики вписываются в «приложение». В конце концов, все в Интернете связано с навигацией, верно? Мы можем ссылаться на что-либо в Интернете с помощью простого тега привязки.

<a href="http://31DaysOfWindows8.com">31 Days of Windows 8</a>

 И когда этого было недостаточно, мы добавили строку запроса, чтобы мы могли получить некоторые данные:

<a href="http://31DaysOfWindows8.com/?days=13">Navigation</a>

И когда в AJAX произошла ночная сенсация в Интернете, мы начали использовать хэш (#) и hashbangs (#!) И создавали эти замечательные веб-приложения:

<a href="http://31DaysOfWindows8.com/#day12">Day 12</a>

Но ты уже знал все это. Так почему же я даже извергал это? Со временем произошла небольшая эволюция того, что мы могли бы считать Веб-сайтом. Сегодня веб-сайты стали скорее приложением, чем то, что мы обычно считаем веб-сайтом. HTML5 был отличным катализатором во всем этом, но в любом случае это должно было произойти.

Несмотря на это, на самом деле появилось два основных «шаблона». Многостраничный сайт ( http://thatConference.com ) и одностраничный сайт ( http://twitter.com или http://OneDay.ThatConference.com ). Хотя они на самом деле не кажутся такими уж разными, их реализации кардинально отличаются. Давайте осторожно разобьем каждого:

Многостраничный сайт:

  • Все начинается на каждой странице навигации, или полный жизненный цикл страницы. 
  • Новые ресурсы загружаются для каждого запроса страницы (снова полный жизненный цикл страницы), это означает страницы JavaScript, CSS и еще много чего.
  • Состояние сеанса, скорее всего, управляется на сервере при условии, что сеанс существует.
  • Взаимодействие между страницами минимально.

образ

Одностраничный сайт:

  • Все работает в контейнере, который был загружен как «элемент управления или раздел» (если хотите)
  • На изображении ниже мы собираемся загрузить страницы в контексте родительской страницы. В нашем случае страница default.html
  • Ресурсы обычно загружаются только один раз (по крайней мере, в самых простых методах)
  • Обычно сильно зависит от большого количества AJAX для извлечения данных при необходимости
  • Любит JavaScript (я делаю на самом деле)

образ

Какой из них вы выбираете? Есть ли правильный ответ? Возможно, но ваш контекст имеет решающее значение для принятия этого решения. Найдите минутку здесь, хорошо. Вы многостраничный сайт или одностраничный сайт? Кроме того, вы многостраничное приложение или одностраничное приложение или вы оба ? Или вы делаете что-то новое в поисках руководства. И кстати, как все это вписывается в Windows 8? Попасть туда..

Хорошо, чтобы не бояться, Windows 8 поддерживает оба точно так же как Ваш Веб-сайт. С одним существенным отличием. У нас нет никаких кнопок навигации или функциональности адресной строки внутри нашего приложения, как в браузере. Сегодня мы собираемся погрузиться в одностраничную модель сайта. Это рекомендуемый Microsoft подход для Магазина Windows 8, и для этого есть несколько причин:

  • Переходы страницы
  • Как загружаются и выгружаются скрипты
  • Управление страницами и государством

Есть несколько конкретных сценариев, которые я хочу осветить в этой статье:

  • Простой акт перехода со страницы A на страницу B в любой из моделей, которые мы описали выше Что происходит, когда и какая информация нам доступна?
  • Передача данных с одной страницы на другую. Это не только строки и целые числа, мы также можем передавать целые объекты между страницами.
  • Состояние страницы

Новое приложение для навигации

Сегодня мы начнем немного по-другому, а скорее начнем с пустого шаблона, который мы начнем с нового шаблона проекта, который называется Приложение навигации . Почему разница? В основном только несколько незначительных вещей:

  • Новый файл JavaScript с именем navigator.js. Это структура, которая помогает вам делать навигацию.
  • В файле default.js добавлено несколько новых ссылок для управления сохранением и загрузкой состояния навигации наших приложений.
  • Слегка другая структура папок приложения. Теперь есть папка страниц с папками страниц.
  • На наших страницах была изменена разметка для использования каркаса navigator.js.

Чтобы лучше увидеть это в действии, давайте просто пройдемся по стеку и посмотрим, что делает наш шаблон, когда мы нажимаем run.

Когда наше приложение запускается впервые, вы заметите, что наша страница по умолчанию имеет те же стандартные ссылки на наши сценарии и стиль WinJS. Конечно, у нас также есть свой собственный файл стилей поддержки и скриптов. Новым в этом шаблоне является добавление фреймворка навигатора:

<script src="/js/navigator.js"></script>

Когда запускается default.js, он выглядит очень похоже, как и в прошлом, за исключением того, что теперь у нас есть новый код для сохранения и загрузки нашего состояния навигации.

app.addEventListener("activated", function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {

        /* .... */

        if (app.sessionState.history) {
            nav.history = app.sessionState.history;
        }
        args.setPromise(WinJS.UI.processAll().then(function () {
            if (nav.location) {
                nav.history.current.initialPlaceholder = true;
                return nav.navigate(nav.location, nav.state);
            } else {
                return nav.navigate(Application.navigator.home);
            }
        }));
    }
});

app.oncheckpoint = function (args) {
    app.sessionState.history = nav.history;
};

Далее сама страница. Наша страница default.html на самом деле собирается загрузить home.html в качестве элемента управления внутри div. Application.PageControlNavigator — это элемент управления внутри фреймворка navigator.js, который мы упоминали ранее. Это должно казаться очень знакомым для нашего разговора в День 4 по элементам управления WinJS .

<body>

    <div id="contenthost" 
            data-win-control="Application.PageControlNavigator" 
            data-win-options="{home: '/pages/home/home.html'}">
    </div>

</body>

Далее, давайте посмотрим на подстраницу, внутреннюю страницу, дочернюю страницу или маленькое поле в большем поле, начиная с его разметки. Поскольку мы являемся подстраницей default.html, нам не нужно ссылаться на фреймворки WinJS, как мы делали в default.html, потому что они уже доступны нам. Остальная часть нашей страницы — просто стандартная разметка ole. Ничего необычного здесь не увидеть. В этом случае кнопка возврата, заголовок и некоторый контент.

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

    <link href="/pages/home/home.css" rel="stylesheet" />
    <script src="/pages/home/home.js"></script>
</head>
<body>
    <div class="fragment homepage">
        <header aria-label="Header content" role="banner">
            <button class="win-backbutton" aria-label="Back" disabled type="button"></button>
            <h1 class="titlearea win-type-ellipsis">
                <span class="pagetitle">Welcome to App16!</span>
            </h1>
        </header>
        <section aria-label="Main content" role="main">
            <p>Content goes here.</p>
        </section>
    </div>
</body>
</html>

Теперь о связанном поведении. Помните, что наша подстраница действительно называется PageControl, найденным в WinJS.UI.Pages . Почему не просто обычная страница? Хорошо, если вы думаете о том, как жизненный цикл страницы действительно работает, мы далеко за пределами этого. Такие вещи, как события стандартной страницы (например, готовый документ), были отброшены, поскольку они действительно произошли на нашей родительской странице. Вот тут-то и появляется наш элемент управления pageControl. Он дает вам представление о том, что вы страница, действующая как обычная страница, даже если это элемент управления внутри другой страницы.

(function () {
    "use strict";

    WinJS.UI.Pages.define("/pages/home/home.html", {
        ready: function (element, options) {
            var isReady = "I am ready are you?";
        }
    });
})();

На данный момент у нас есть работающее приложение, которое использует инфраструктуру навигации с бонусными баллами, потому что мы сохраняем наше состояние навигации в наших приложениях sessionState через события PLM. Я знаю, что шаблон сделал все это для тебя, но только не говори об этом своему боссу.

Прежде чем мы продолжим, давайте создадим еще одну страницу home2, по которой мы тоже сможем ориентироваться. Мы можем легко сделать это, добавив новый элемент под названием pageControl. Элемент управления страницей — это не что иное, как файлы html, js и css, которые уже наполовину подключены, чтобы вы начали возиться с ними. Я говорю полу, потому что в зависимости от того, как вы его используете, вы можете удалить некоторые ссылки на WinJS, поскольку они есть на вашей родительской странице.

образ

Навигация между страницами

Мы начали эту статью с краткого обзора набора якорных тегов, которые перенесут вас в другой документ или в другое место на сайте \ в приложении. То же самое верно для приложения Магазина Windows. Простой тег привязки перенаправит вас с одной страницы верхнего уровня на другую.

<a href="/pages/home2/home2.html">Goto MultiPage Navigation</a>

Который будет работать нормально, и можно было создать такое приложение без проблем. Но сегодня я хочу сосредоточиться на модели одностраничной навигации, о которой мы говорили ранее. Для этого мы будем использовать навигационную структуру, которую мы уже кратко представили. Как вы можете себе представить, мы будем вызывать метод с именем navigate, передавая его нашему месту назначения.

WinJS.Navigation.navigate(“/pages/home2/home2.html”); 

Далее нам нужно фактически использовать нашу навигационную структуру. Чтобы легко это сделать, мы действительно хотим заменить стандартное поведение наших стандартных тегов привязки. Мы можем легко угнать их поведение, предварительно подключив их к такому событию:

WinJS.Utilities.query("a").listen("click", anchorHandler, false);

а затем не дает им делать то, что они обычно делают, а скорее называют WinJS Navigation.

function anchorHandler(eventInfo) {
    eventInfo.preventDefault();
    var link = eventInfo.target;

    WinJS.Navigation.navigate(link.href);
}

Теперь все наши теги привязки не будут ссылаться, как обычно, а будут использовать нашу навигационную среду для перехода к другим элементам управления страницы. Конечно, это не просто якорный тег, но я иду по легкой дороге здесь.

Теперь это привело нас куда-то, а как насчет возвращения? Помните, что у нас нет кнопок браузера «назад» и «вперед» и, более того, браузер и \ или HTML5 History API могли бы \ отслеживать это для вас (это зависит от того, как вы настроили). То же самое верно, когда вы используете навигацию WinJS. Навигатор хранит историю наших сессий и имеет в своем распоряжении ряд методов и событий. Если вы используете шаблон, вы можете заметить кнопку возврата в верхней части второй страницы, и если вы нажмете на нее, вы волшебным образом вернетесь назад. Ну не совсем. На самом деле все, что он делает, это вызывает один из этих методов в WinJS.Navigation, в частности, back () . Вы можете увидеть это прямо в файле navigator.js.

_updateBackButton: function () {
    var backButton = this.pageElement.querySelector("header[role=banner] .win-backbutton");
    if (backButton) {
        backButton.onclick = function () { nav.back(); };

        if (nav.canGoBack) {
            backButton.removeAttribute("disabled");
        } else {
            backButton.setAttribute("disabled", "disabled");
        }
    }
},

Передача данных

Далее мы хотим передать данные между нашими страницами. Может быть, объект, может быть строка, но, тем не менее, данные. Оказывается, наш метод WinJS.Navigation.navigate перегружен, чтобы также принять параметр данных. Поэтому я просто собираюсь создать простой маленький объект и изменить свой вызов, чтобы перейти к нему в одиночку.

var myData = {
    firstName: "Clark",
    lastName: "Sell"
};

....

WinJS.Navigation.navigate(link.href, myData);

....

Затем на принимающей стороне этого вызова он приходит к нам в качестве параметров готового обработчика для нашего pageControl.

ready: function (element, options) {
    var results = document.querySelector("#results");
    results.innerText = options.firstName + " " + options.lastName;
}

Я не думаю, что это становится намного легче.

Жизненный цикл приложения

А теперь, если ваше приложение опустилось на несколько уровней, а затем пользователь переключился на что-то другое, забыв, что он или она его запускали Windows приостанавливает это и что тогда? Все потеряно? Надеюсь нет. Мы бы хотели, чтобы пользователь возобновил работу с того места, где он остановился, и если это означает, что сначала нужно нажать кнопку «Назад», он должен это сделать. Ну, это на самом деле правда. Мы коснулись этого ранее, но давайте кратко рассмотрим, что делал этот код в шаблоне.

Прежде чем ваше приложение приостановится, оно вызовет контрольную точку. Это наша возможность взять наше состояние навигации и сохранить его.

app.oncheckpoint = function (args) {
    app.sessionState.history = nav.history;
};

Теперь, когда вещи спасены, что происходит в другом направлении, когда все начинается. Ну, честно говоря, он делает то, что вы думаете.

  • Проверьте ваши приложения sessionState для любой истории
  • Если есть, повторно заполните историю навигации
  • Затем после того, как все элементы управления обработаны, посмотрите, был ли пользователь где-то
  • Верните пользователя в правильное местоположение.
app.addEventListener("activated", function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
            // TODO: This application has been newly launched. Initialize
            // your application here.
        } else {
            // TODO: This application has been reactivated from suspension.
            // Restore application state here.
        }

        if (app.sessionState.history) {
            nav.history = app.sessionState.history;
        }
        args.setPromise(WinJS.UI.processAll().then(function () {
            if (nav.location) {
                nav.history.current.initialPlaceholder = true;
                return nav.navigate(nav.location, nav.state);
            } else {
                return nav.navigate(Application.navigator.home);
            }
        }));
    }
});

Честно говоря, ничего сложного, и, поскольку это сделано для вас, ну, еще проще, но вы должны знать, что, по крайней мере, происходит.

Резюме

Проще, чем использовать GPS, чтобы найти ближайшее метро? Может быть. Это не слишком сложно, и на самом деле фреймворки уже существуют, чтобы действительно поддержать нас. Конечно, сегодняшние приложения могут быть очень сложными, поэтому не думайте, что ваша работа выполнена за вас. Сегодня мы рассмотрели модели навигации, шаблон приложения Navigator, навигацию назад и вперед и даже сохранили историю навигации на случай, если наше приложение будет приостановлено.

Если вы хотите загрузить полный пример кода из этой статьи, вы можете щелкнуть значок ниже.

downloadHTML

Завтра мы начнем нашу беседу с определения текущего местоположения пользователя с помощью GeoLocation, включая правила, которые применяются при использовании этой технологии. Увидимся позже!

downloadTheTools