在 jQuery Mobile 和 PhoneGap 中创建模板化/持久页眉/页脚模板
我正在深入使用 jQuery Mobile/PhoneGap 编写移动应用程序。我正在使用此示例模板 首先,它使用 HTML/JS 创建页面。他没有将所有
标签放在一个 html 文件中,而是将其分开,以便更容易编辑。
由于我将为每个页面都有一个单独的文件,因此包含模板页眉/页脚的最佳方式是什么?我只在需要复制并粘贴整个页脚 -> 导航栏的地方看到它代码到每个 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>');
}
I'm diving into writing a mobile app with jQuery Mobile/PhoneGap. I'm using this sample template to start from, which uses HTML/JS to create the pages. Rather than have all the <page>
tags in one single html file, he's got it split up so it's easier to edit.
Since I will have a separate file for each page, what's the best way to include the tempated header/footer? I've only seen it where you need to copy and paste the whole footer->navbar code into each HTML page. This doesn't seem like it should be. For example, if you want to change one menu item, you need to go into each page and change it.
What's the solution that I'm missing?
Maybe I'm just not understanding jQuery Mobile. For example, their sidebar they use for their docs - is that sidebar code copy and pasted onto each page? That doesn't make sense. It's the same idea as the question I'm asking here about the footer.
http://jquerymobile.com/test/docs/pages/page-cache.html
This is what I've got that doesn't seem right (and $.live('pageinit')
isn't working). This HTML is what goes on each HTML page:
<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;">
And the 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>');
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
几天来我一直在尝试解决这个问题,并且已经非常接近解决方案。我使用以下 HTML:
并且我创建了以下函数来使用 ajax 加载菜单/内容:
.trigger('create');
和.navbar(); 是保持 JQM 样式正确所需的方法,但是,仍然存在一个小错误。菜单的位置(使用 css top: ...px 设置)有时不正确,并在第一次点击后自行移动到正确的位置。虽然真的很接近!
编辑:通过将
#footer
设置为position:fixed;
,我上面提到的小错误就消失了。此外,如果由top
值引起的位置为JQM 是不正确的。I've been trying to tackle this problem for a few days now and I've gotten really close to the solution. I use the following HTML:
And I've created the following functions to load the menu/content using ajax:
The
.trigger('create');
and.navbar();
are the methods required to keep the JQM styling correct, however, there's still one little bug. The position of the menu (which is set using css top: ...px) is sometimes not correct and moves itself to the correct position after the first tap. Really close though!Edit: By setting
#footer
toposition: fixed;
the minor bug I mentioned above is gone. Also, it's easy to make a method that calculates thetop
(in px) for the#footer
if the position caused by thetop
value by JQM is incorrect.像这样的事情:
您可以在 getText 中定义 role=footer 并检查它是否已定义...如果没有,则添加它。
Something like this:
you could just define the role=footer in the getText and just check to see if it's defined... if not then add it.
如果你真的想正确地做到这一点,你需要研究像 Thorax 或 JavascriptMVC 这样的 js 框架。
在 JMVC 应用程序中,您可以从任何视图执行此操作:
jQuery Mobile 实际上仅适用于移动设备的渐进式标记增强和样式设置。对于实际的 MVC 部分,您需要一个 MVC 框架。
jQuery Mobile 的示例也主要用于构建移动网站,因为它们从服务器获取页面,假设您的代码重用发生在服务器端。
Phonegap 应用程序完全是另一种野兽,因为您将动态或从本地静态文件生成这些页面。当您使用控制器、视图、视图助手和模型类构建页面时,MVC 框架就出现了。您可以通过监听 pagebeforeshow 事件将所有这些绑定到 jQuery mobile,如 脚本页面
If you really want to do this properly, you need to look into a js framework like Thorax or JavascriptMVC.
In a JMVC app, you could do this from any view:
jQuery Mobile is really only useful for progressive markup enhancement and styling for mobile devices. For the actual MVC part you need an MVC framework.
The examples for jQuery Mobile are also mostly geared for building mobile web sites which since they fetch pages from a server assume your code reuse is happening server side.
A phonegap app is a whole nother beast since you will be generating these pages on the fly or from local static files. This is were the MVC framework comes in as you would be building your pages using controllers, views, view helpers, and model classes. You tie all that into jQuery mobile by listening to the pagebeforeshow event as shown on the jQm documentation page on scripting pages
我们还没有找到一个好的方法来做到这一点。所以我们实际上是在自定义 js 文件中动态处理这个问题。寻找关闭容器 - 然后在最后一个内容 div 关闭后动态附加页脚。
We haven't found a good way to do this yet either. So we are actually handling this dynamically in our custom js file. Looking for the closing container - and then dynamically appending the footer after the last content div closes.
取决于您如何加载各个页面。
如果您使用 rel="external" - 无 AJAX,每个页面都将完全重新加载。
如果您使用常规 JQM - AJAX,JQM 将抓取页面并将其附加到您现有的 DOM。将您的第一页视为“锚”页面,所有后续页面都会添加/删除。
在第二种情况下,您可以在每个页面上想要的元素上指定 data-append-to-all-pages="true" 属性。
然后只需监听相应的事件(pagebeforeshow?)并在显示之前将具有上述标签的元素添加到新页面。这样,元素只需在第一页上设置,然后自动添加到任何被拉入并添加到 DOM 的后续页面。
我现在正在使用登录表单来研究这个问题,我在登录之外的每个页面上都需要该表单,并且必须避免以重复的 input#someID 结束。
编辑 - 可能的解决方案
将相应的元素放在第一页上并添加唯一的属性,如下所示:
所有其他页面仅获取唯一的元素容器
然后使用此脚本:
当然,这意味着您需要唯一的每个页面上的容器。但是,当您浏览该应用程序时,您只需携带它的内容即可。应该对我有用,并避免在 DOM 中使用相同的登录表单 2 次以上。
另外,您可以自由编辑其内容,例如添加活动课程。
Depends how you load the respective pages.
If you use rel="external" - no AJAX, each page will be reloaded completely.
If you use regular JQM - AJAX, JQM will grab the page and attach it to your existing DOM. Think of your first page as your "anchor" page, which all subsequent pages are added/removed.
In the 2nd case you could specify a data-append-to-all-pages="true" attribute on elements you want to have on every page.
Then just listen to the respective event (pagebeforeshow?) and add elements with the above label to the new page before it's shown. This way elements would only have to be set on the first page and then automatically be added to any subsequent page being pulled in and added to the DOM.
I'm looking into this right now with a login form, which I need on every page outside the login and have to avoid ending up with duplicate input#someID.
EDIT - possible solution
Put the respective element on the first page and add unique attributes, like so:
All other pages just get the unique element container
Then use this script:
Of course this would mean you need the unique container on every page. But then you would just carry the content of it along as you traverse through the app. Should work for me and avoid having the same login form 2+ times inside the DOM.
Plus you would be free to edit it's contents for example adding active class.
不要使用 pageinit,您应该监听的事件是 pagecreate 和 pageshow,pagecreate 在页面第一次加载时被调用,但在您导航回页面时(例如在后退按钮上)不会被调用。鉴于每次显示页面时 pageshow 都会触发,因此只需将实时侦听器绑定到添加页脚的每个页面的 pageshow 事件(假设页脚可能会更改,否则使用 pagecreate)。
我有一个更长的示例,向您展示如何在另一个问题中正确绑定到事件: https://stackoverflow.com/a/9085014 /737023
是的,一个很好的解决方案就是使用 PHP/CF 包含,这就是我使用的而不是 JS。
编辑
不好的是,现在似乎使用 pageinit 而不是 pagecreate (参见此处),但每次显示页面时 pageshow 仍然会触发 - 因此您可以根据需要使用它们
Don't use pageinit, the events that you should listen for are pagecreate and pageshow, pagecreate gets called the first time a page is loaded, but not when you navigate back to the page, e.g. on back button. Whereas pageshow fires everytime a page is shown, so just bind a live listener to the pageshow event for every page where you add your footer (assuming your footer may change, otherwise use pagecreate).
I have a longer example that shows you how to bind to the event properly in another question: https://stackoverflow.com/a/9085014/737023
And yes a great solution is just to use a PHP/CF include, which is what I use instead of JS.
EDIT
My bad, seems pageinit is now used instead of pagecreate (see here), but it still stands that pageshow fires every time a page is shown - so you can use those as you need