Создание шаблона/стойкого шаблона заголовка/нижнего колонтитула в jQuery Mobile и PhoneGap

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

Так как у меня будет отдельный файл для каждой страницы, какой лучший способ включить tempated header/footer? Я видел его только там, где вам нужно скопировать и вставить весь нижний колонтитул, > код навигатора на каждую 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>');
}

Ответ 1

Я пытался решить эту проблему в течение нескольких дней, и я очень близко подошел к решению. Я использую следующий 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 (в px) для #footer, если неправильная позиция, вызванная значением top JQM.

Ответ 2

Что-то вроде этого:

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 и просто проверить, не определено ли это... если нет, то добавьте его.

Ответ 3

Если вы действительно хотите сделать это правильно, вам нужно заглянуть в фреймворк 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 на страницах .

Ответ 4

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

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

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

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

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

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

EDIT - возможное решение

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

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

Затем используйте этот script:

$('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.

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

Ответ 5

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

Ответ 6

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

У меня есть более длинный пример, который показывает, как правильно привязать событие к другому вопросу: fooobar.com/info/91412/...

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


ИЗМЕНИТЬ Мой плохой, кажется, что pageinit теперь используется вместо pagecreate (см. Здесь), но по-прежнему стоит, что при каждом показе страницы срабатывает каждый раз, поэтому вы можете использовать те, которые вам нужны