Статьи

Работа с мобильными панелями jQuery

jQuery Mobile — это платформа с открытым исходным кодом, которая позволяет разработчикам легко создавать мобильные веб-сайты и гибридные приложения. Используя (в основном) HTML, вы можете быстро создать одностраничную архитектуру с простой в использовании системой страниц и виджетами для форм, всплывающих окон и других элементов пользовательского интерфейса. Одним из более новых виджетов для входа в инфраструктуру jQuery Mobile является виджет «Панели». В этой статье я объясню, как использовать панели, и дам вам пример того, как создать панель с динамическим содержимым.

Я предполагаю, что вы уже немного знаете о том, как работает jQuery Mobile. Если вы этого не сделаете, то я настоятельно рекомендую вам ознакомиться с их превосходным руководством по началу работы . По сути, jQuery Mobile работает с обычной разметкой, добавляя немного стиля с помощью атрибутов data5 * HTML5. Эти атрибуты данных помогают jQuery Mobile определять страницы и другие виджеты пользовательского интерфейса. Вот простой пример мобильного приложения jQuery с двумя страницами:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
    </head>

    <body>

        <div data-role="page" id="home">

            <div data-role="header">
<h1>Welcome to Foo</h1>
</div>

            <div data-role="content">

                <p>
                This is some simple content just to fill up some space. Nothing really exciting to see here.
                </p>
                <p>
                <a href="#second" data-role="button">Go to Second</a>
                </p>

            </div>

            <div data-role="footer">
                <h4>Copyright NoOneImportant</h4>
            </div>

        </div>

        <div data-role="page" id="second">

            <div data-role="header">
                <a href="#home" data-icon="home" data-iconpos="notext">Home</a>
                <h1>Welcome to Foo</h1>
            </div>


            <div data-role="content">

                <p>
                This is some other page.
                </p>

            </div>

            <div data-role="footer">
                <h4>Copyright NoOneImportant</h4>
            </div>

        </div>

    </body>
</html>

Даже если вы впервые видите jQuery Mobile, вы можете сделать разумное предположение о том, что здесь происходит. У нас есть два больших блока, определенных как data-role="page". Внутри каждого находятся верхние и нижние колонтитулы и содержимое главной страницы. Когда jQuery Mobile загрузит его, он автоматически отобразит только первую страницу и обновит ваш HTML, чтобы выглядеть лучше на мобильном устройстве. Вот как это выглядит в iOS:

Что не очевидно из скриншотов, так это приятные переходы между страницами. jQuery Mobile автоматически обнаруживает ссылки и преобразует их в GET на основе Ajax, чтобы помочь создать одностраничную архитектуру. Примечание. Хотя у меня есть две страницы в одном и том же HTML-файле выше (и jQuery Mobile поддерживает это), вы абсолютно не должны (и не должны) создавать все приложение в одном файле. Если бы я связался с two.html и просто переместил свою страницу div в этот файл, конечный результат был бы точно таким же.

Отправить в панели

Итак, теперь, когда вы увидели базовый пример jQuery Mobile, давайте поговорим о виджете «Панели». Один из способов, который разработчики мобильных устройств придумали, чтобы помочь справиться с ограниченным пространством на мобильном устройстве, — это использовать боковую панель. По сути, контент, который скрывается с левой или правой стороны области просмотра. Когда срабатывает определенное действие пользователя (смахивание или нажатие кнопки), панель выдвигается и открывает дополнительный контент.

jQuery Mobile 1.3.1 поддерживает все вышеперечисленное. Давайте посмотрим на простой пример. В следующем примере кода я добавил новый div в структуру моей страницы, которая использует роль данных панели. Также обратите внимание, что я дал ему идентификатор:

        <div data-role="page" id="home">

            <div data-role="panel" id="firstpanel">
                This is my panel content.
            </div>

            <div data-role="header">
                <h1>Welcome to Foo</h1>
            </div>

            <div data-role="content">

                <p>
                This is some simple content just to fill up some space. Nothing really exciting to see here.
                </p>
                <p>
                <a href="#firstpanel" data-role="button">More Detail</a>
                </p>

            </div>

            <div data-role="footer">
                <h4>Copyright NoOneImportant</h4>
            </div>

        </div>

Когда jQuery Mobile загрузит эту страницу, он заметит, что div настроен как панель, и автоматически скроет ее. Так как же нам это показать? Просто. Ссылка на моей странице напрямую указывает на идентификатор, который мы использовали (первая панель). Нажав (или коснувшись), он будет скользить в панели слева.

Как бы вы использовали панель, которая появилась справа? Просто добавьте data-position в ваш div:

<div id="thePanel" data-role="panel" data-position="right">

А как насчет закрытия панели? По умолчанию вы можете закрыть панель, просто щелкнув за ее пределами или проведя пальцем. Это может быть не то, что вы хотите, хотя. Вы можете отключить любую из этих функций, используя дополнительные атрибуты данных. Используйте функцию data-swipe-close, чтобы отключить функцию «сильно ударить, чтобы закрыть», и data-disptables, чтобы предотвратить щелчок / касание, скрывающее панель. В приведенном ниже фрагменте оба отключены:

<div id="thePanel" data-role="panel" data-position="right" data-swipe-close="false" data-dismissible="false">

Это, конечно, поднимает вопрос: если вы удалите все способы, которыми пользователь может закрыть панель, как еще пользователь сможет закрыть ее? Если вы хотите, вы можете просто добавить свою собственную кнопку на панели, которая использует атрибут data-rel = «close». Вот простая панель, которая демонстрирует это. (Вы можете проверить это самостоятельно в файле .zip, прилагаемом к этой статье. Файл test2.html.)

<div data-role="panel" id="firstpanel" data-swipe-close="false" data-dismissible="false">
    <h3>My Panel</h3>
    <p>
    This is my panel content.
    </p>
    <p>
    <a data-rel="close" data-role="button">Hide</a>
    </p>
</div>

Наконец, вы также можете управлять тем, как панель отображается для пользователя, когда она выходит. Это называется режимом отображения и определяется с помощью отображения данных. Ваши варианты наложения, раскрытия и толчка. Оверлей делает то, что вы ожидаете: он отображает панель поверх вашего контента. И раскрытие, и нажатие подталкивают ваш контент, но раскрытие использует эффект 3D, как будто ваша панель скрывалась под содержимым. Значением по умолчанию является раскрытие.

Построение динамической панели

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

Для получения данных о погоде мы будем использовать отличный и бесплатный сервис OpenWeatherMap . Это 100% бесплатный API с интерфейсом JSON / P.

Во-первых, давайте просто настроим шаблон. В приведенном ниже примере вы можете увидеть новую панель под названием Weatherpanel. Также обратите внимание, что мы добавили кнопку в заголовок, чтобы отобразить ее. Этот фрагмент можно найти в test3.html. Пока нет никакой логики — только начальный интерфейс.

        <div data-role="page" id="home">

            <div data-role="panel" id="weatherpanel" data-theme="a">
                <h3>Current Weather</h3>
                <p class=">
                </p>
                <p>
                <a data-rel="close" data-role="button" data-theme="a">Dismiss</a>
                </p>
            </div>

            <div data-role="header">
                <a href="#weatherpanel" data-icon="gear" data-iconpos="notext">Weather</a>
                <h1>Welcome to KRKC</h1>
            </div>

            <div data-role="content">

                <p>
                This is some simple content just to fill up some space. Nothing really exciting to see here.
                </p>

            </div>

            <div data-role="footer">
                <h4>Copyright NoOneImportant</h4>
            </div>

        </div>

Так что теперь нам нужно на самом деле сделать эту работу. Я добавил новый файл JavaScript в свой проект. Давайте посмотрим на это ниже.

var weatherloaded = false;
var weathericonurl = "http://openweathermap.org/img/w/";

$(document).on("panelbeforeopen", "#weatherpanel", function(e, ui) {

    var panel = this;

    //Do we have our weather data?
    if(!weatherloaded) {

        $("p.weather", panel).html("<i>Fetching weather - please stand by!</i>");

        $.get("http://api.openweathermap.org/data/2.5/weather?q=lafayette,la&units=imperial", function(res,code) {
            /*
            Generate a weather string. This could be nicer if it used something like Handlebars
            */
            var s = "";
            s += "<p>The current temperature is "+ Math.round(res.main.temp) + " degrees. Today's low will " + 
                 "be " + Math.round(res.main.temp_min) + " degrees with a high of " + 
                 Math.round(res.main.temp_max) + " degrees.</p>";

            //weather is optional
            if(res.weather && res.weather.length >= 1) {
                s += "<p><img style='width:100px' src='" + weathericonurl + res.weather[0].icon + ".png'></p>";
            }

            $("p.weather", panel).html(s);
            $(panel).trigger( "updatelayout" );            
            weatherloaded = true;

        }, "JSONP");

    }

});

Почти весь фрагмент кода является обработчиком событий для панели. Все виджеты jQuery Mobile содержат различные события, которые вы можете прослушивать в своем коде. В нашем демо мы хотим послушать событие panelbeforeen. Как вы можете догадаться, это будет выполняться при каждом открытии панели.

Хотя API OpenWeatherMap прост в использовании, мы действительно не хотим получать погоду при каждом открытии панели. Поэтому мы используем простую булеву переменную, Weatherloaded, чтобы показать, что погода была загружена. Если погода еще не загружена, мы делаем вызов API. Как мы уже говорили выше, мы используем жестко запрограммированное местоположение (в данном случае мой любимый родной город Лафайет, Луизиана). Когда результат возвращается, мы создаем строку HTML, которую можно вставить в панель.

Документы jQuery Mobile рекомендуют запускать событие updatelayout всякий раз, когда вы изменяете содержимое панели, поэтому мы делаем это также.

Результатом является панель, которая отображает погоду, но также достаточно умна, чтобы загружать данные только по запросу. Если вы никогда не открываете панель, она пропускает вызов. Вот результат:

Куда идти дальше

Если вам понравилось это и вы хотите узнать больше о jQuery Mobile Panels, посмотрите ссылку на виджет . Кроме того, вы можете рассмотреть книгу «Основы разработки мобильных веб-приложений jQuery», написанную мной и Энди Мэтьюсом. В настоящее время книга обновляется до самой последней версии jQuery Mobile (так что, честно говоря, вы можете подождать!).

Эта статья была написана по заказу Intel и команды разработчиков Tizen Mobile.