Создание шаблонного / постоянного шаблона верхнего / нижнего колонтитула в jQuery Mobile и PhoneGap - PullRequest
61 голосов
/ 05 февраля 2012

Я погружаюсь в написание мобильного приложения с jQuery Mobile / PhoneGap. Я использую этот образец шаблона для начала, который использует HTML / JS для создания страниц. Вместо того, чтобы иметь все теги <page> в одном HTML-файле, он разбит на части, поэтому его проще редактировать.

Поскольку у меня будет отдельный файл для каждой страницы, как лучше всего включить искомый верхний / нижний колонтитул? Я видел его только там, где нужно скопировать и вставить весь нижний колонтитул-> Код Navbar в каждую страницу HTML. Это не похоже на то, что должно быть. Например, если вы хотите изменить один пункт меню, вам нужно перейти на каждую страницу и изменить его.

Какое решение мне не хватает?

Может быть, я просто не понимаю jQuery Mobile. Например, их боковую панель, которую они используют для своих документов - этот код боковой панели копируется и вставляется на каждую страницу? Это не имеет смысла. Это та же идея, что и вопрос, который я задаю здесь о нижнем колонтитуле.

http://jquerymobile.com/test/docs/pages/page-cache.html

Это то, что у меня есть, и это не так (а $.live('pageinit') не работает). Этот HTML - то, что идет на каждой странице HTML:

<div id="mainFooter" data-position="fixed" data-id="mainFooter" data-role="footer" class="ui-footer ui-bar-a ui-footer-fixed fade ui-fixed-inline" role="contentinfo" style="top: 58px;">

И JS

$.live('pageinit', function (event) {
    displayFooter();
});

function displayFooter() {
    $('#mainFooter').html('<div data-role="navbar" class="nav-glyphish-example" data-grid="d">' +
        '<ul>' +
        '<li><a href="#" id="menuitem1" data-icon="custom">Menu Item 1</a></li>' +
        '<li><a href="#" id="menuitem2" data-icon="custom">Menu Item 2</a></li>' +
        '<li><a href="#" id="menuitem3" data-icon="custom">Menu Item 3</a></li>' +
        '</ul>' +
        '</div>');
}

Ответы [ 6 ]

22 голосов
/ 11 февраля 2012

Я уже несколько дней пытаюсь решить эту проблему, и я очень близко подошел к решению. Я использую следующий HTML:

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

        <div data-role="header">
            <h1 id="title">Title</h1>
        </div><!-- /header -->

        <div data-role="content" id="content">  
            <p>Loading...</p>
        </div><!-- /content -->

        <div data-role="footer" id="footer" data-position="fixed">
            <div data-role="navbar" id="navbar">
            </div>
        </div><!-- /footer -->
    </div><!-- /page -->
</body>

И я создал следующие функции для загрузки меню / контента с помощью ajax:

$(document).on('pageinit', "#page", function() {
    // for example: displayFooter();
    loadContent("main");
    loadMenu("default");
});

function loadContent(location) {
    return $('#content').load("views/content/"+location+".html", function() { 
        $(this).trigger('create');
    });
}
function loadMenu(location) {
    $("#menu").remove();
    $("#navbar").remove();

    $("#footer").html('<div data-role="navbar" id="navbar">');
    $("#navbar").html('<ul id="menu"></ul>');

    $("#menu").load("views/menus/"+location+".html", function() { $("#menu").parent().navbar(); });

    return true;
}

.trigger('create'); и .navbar(); - это методы, необходимые для поддержания правильного стиля JQM, однако есть еще одна небольшая ошибка. Положение меню (которое задается с помощью css top: ... px) иногда неверно и перемещается в правильное положение после первого касания. Действительно близко, хотя!

Редактировать: При установке #footer на position: fixed; небольшая ошибка, о которой я упоминал выше, исчезла. Кроме того, легко создать метод, который вычисляет top (в пикселях) для #footer, если позиция, вызванная значением top JQM, неверна.

3 голосов
/ 10 февраля 2012

Если вы действительно хотите сделать это правильно, вам нужно изучить js-фреймворк, такой как Thorax или JavascriptMVC.

В приложении JMVC вы можете сделать это из любого представления:

<div data-role="page">
    <%== $.View('./header.ejs') %>
    <div data-role="content">
    ...
    </div>
    <%== $.View('./footer.ejs') %>
</div>

jQuery Mobile действительно полезен только для прогрессивного улучшения разметки и стиля для мобильных устройств. Для фактической части MVC вам нужна структура MVC.

Примеры для jQuery Mobile также в основном предназначены для создания мобильных веб-сайтов, которые, поскольку они выбирают страницы с сервера, предполагают, что повторное использование кода происходит на стороне сервера. Приложение PhoneGap - это совершенно другой зверь, так как вы будете генерировать эти страницы на лету или из локальных статических файлов. Это как раз то, что MVC-фреймворк вводит так, как вы бы строили свои страницы с использованием контроллеров, представлений, помощников представлений и классов моделей. Вы привязываете все это к мобильному jQuery, прослушивая событие pagebeforeshow, как показано на странице документации jQm на страницах сценариев

3 голосов
/ 09 февраля 2012

Примерно так:

function getText() {
    //return footer text here
}


$("div:jqmData(role='page')").live("pagebeforecreate",function() {
    // get find the footer of the page
    var $footer =$(this).page().find('div:jqmData(role="footer")')
    // insert it where you want it... 
}

Вы можете просто определить role = footer в getText и просто проверить, определено ли оно ... если нет, то добавьте его.

2 голосов
/ 07 февраля 2012

Не используйте pageinit, события, которые вы должны прослушивать, это pagecreate и pageshow, pagecreate вызывается при первой загрузке страницы, но не при переходе обратно на страницу, например, при нажатии кнопки «Назад».Принимая во внимание, что pagehow запускается каждый раз, когда отображается страница, поэтому просто привяжите живой слушатель к событию pagehow для каждой страницы, где вы добавляете свой нижний колонтитул (при условии, что ваш нижний колонтитул может измениться, в противном случае используйте pagecreate).

У меня есть более длинный примерэто показывает вам, как правильно связать событие с другим вопросом: https://stackoverflow.com/a/9085014/737023

И да, отличное решение - просто использовать PHP / CF include, что я и использую вместо JS.

РЕДАКТИРОВАТЬ Мой плохой, кажется, pageinit теперь используется вместо pagecreate (см. Здесь) , но он по-прежнему показывает, что pagehow запускается каждый раз, когда отображается страница - так что вы можете использовать их как вынеобходимо

2 голосов
/ 06 февраля 2012

Мы еще не нашли хорошего способа сделать это. Таким образом, мы фактически обрабатываем это динамически в нашем пользовательском файле js. Ищем закрывающий контейнер, а затем динамически добавляем нижний колонтитул после закрытия последнего содержимого div.

2 голосов
/ 06 февраля 2012

Зависит от того, как вы загружаете соответствующие страницы.

Если вы используете rel = "external" - без AJAX, каждая страница будет полностью перезагружена.

Если вы используете обычный JQM - AJAX, JQM захватит страницу и прикрепит ее к существующей DOM. Думайте о своей первой странице как о своей «якорной» странице, которая добавляет / удаляет все последующие страницы.

Во втором случае вы можете указать атрибут data-append-to-all-pages = "true" для элементов, которые вы хотите иметь на каждой странице.

Затем просто прослушайте соответствующее событие (pagebeforeshow?) И добавьте элементы с надписью выше на новую страницу, прежде чем она будет показана. Таким образом, элементы должны быть установлены только на первой странице, а затем автоматически добавлены на любую последующую страницу, которая загружается и добавляется в DOM.

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

РЕДАКТИРОВАТЬ - возможное решение

Поместите соответствующий элемент на первую страницу и добавьте уникальные атрибуты, например:

 <div data-role="navbar" data-unique="true" data-unique-id="log">
     // full navbar
 </div>

Все остальные страницы просто получают уникальный контейнер элемента

<div data-role="navbar" data-unique="true" data-unique-id="log"></div>

Тогда используйте этот скрипт:

$('div:jqmData(role="page")').live('pagebeforehide', function(e, data) {

    //  check page you are leaving for unique items 
    $(this).find('div:jqmData(unique="true")').each(function(){

         // more or less 1:1 stickyFooter
         var uniqueID = $(this).jqmData("unique-id"),
             nextPage = data.nextPage,
             nextUnique = nextPage && nextPage.find( "div:jqmData(unique-id='"+uniqueID+"')" ),
             nextMatches = nextUnique.length && nextUnique.jqmData('unique-id') === uniqueID;

         // if unique items on previous and new page are matching
         if ( uniqueID && nextMatches ) {
            nextUnique.replaceWith( uniqueID );
            $(this).jqmData("unique-id").empty();
            }
         });
     }); 

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

Кроме того, вы можете свободно редактировать его содержимое, например, добавляя активный класс.

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