Создание шаблона/стойкого шаблона заголовка/нижнего колонтитула в 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 (см. Здесь), но по-прежнему стоит, что при каждом показе страницы срабатывает каждый раз, поэтому вы можете использовать те, которые вам нужны