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


я погружаюсь в написание мобильного приложения с помощью 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 60

6 ответов:

Я пытался решить эту проблему в течение нескольких дней теперь и я получил очень близко к решению. Я использую следующий 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;
}

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

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

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

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

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

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

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

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

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

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

во втором случае вы можете указать атрибут data-append-to-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>

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

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

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

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

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

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


EDIT Мой плохой, кажется pageinit теперь используется вместо pagecreate (см. здесь), но он по - прежнему стоит, что pageshow срабатывает каждый раз, когда страница отображается-так что вы можете использовать их, как вам нужно