61 votes

Création de modèles d'en-tête/pied de page en jQuery Mobile et PhoneGap

Je me lance dans l'écriture d'une application mobile avec jQuery Mobile/PhoneGap. J'utilise ce modèle type pour commencer, qui utilise HTML/JS pour créer les pages. Plutôt que d'avoir toutes les <page> dans un seul fichier html, il l'a séparé pour qu'il soit plus facile à modifier.

Puisque j'aurai un fichier distinct pour chaque page, quelle est la meilleure façon d'inclure l'en-tête et le pied de page temporisés ? Je ne l'ai vu que lorsque vous devez copier et coller le code entier du pied de page->barre de navigation dans chaque page HTML. Cela ne semble pas devoir être le cas. Par exemple, si vous voulez changer un élément de menu, vous devez aller dans chaque page et le changer.

Quelle est la solution qui me manque ?

Peut-être que je ne comprends pas bien jQuery Mobile. Par exemple, la barre latérale qu'ils utilisent pour leurs documents - le code de cette barre latérale est copié et collé sur chaque page ? Cela n'a pas de sens. C'est la même idée que la question que je pose ici sur le pied de page.

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

Voici ce que j'ai obtenu et qui ne semble pas correct. $.live('pageinit') ne fonctionne pas). Ce HTML est ce qui va sur chaque page 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;">

Et la 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>');
}

22voto

bartolsthoorn Points 956

J'essaie de m'attaquer à ce problème depuis quelques jours maintenant et je suis très près de la solution. J'utilise le HTML suivant :

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

Et j'ai créé les fonctions suivantes pour charger le menu/contenu en utilisant 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;
}

El .trigger('create'); y .navbar(); sont les méthodes requises pour garder le style JQM correct, cependant, il y a encore un petit bug. La position du menu (qui est définie à l'aide de css top : ...px) n'est parfois pas correcte et se met à la bonne position après le premier tapotement. Mais c'était presque ça !

Edit : En fixant #footer a position: fixed; le bug mineur que j'ai mentionné ci-dessus a disparu. De plus, il est facile de créer une méthode qui calcule la valeur de top (en px) pour le #footer si la position causée par le top valeur par JQM est incorrecte.

3voto

bmurmistro Points 545

Quelque chose comme ça :

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

vous pourriez simplement définir le role=footer dans le getText et vérifier s'il est défini... si non, ajoutez-le.

3voto

Yacine Filali Points 808

Si vous voulez vraiment faire cela correctement, vous devez vous pencher sur un framework js comme Thorax ou JavascriptMVC.

Dans une application JMVC, vous pourriez faire cela à partir de n'importe quelle vue :

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

jQuery Mobile n'est vraiment utile que pour l'amélioration progressive du balisage et du style pour les appareils mobiles. Pour la partie MVC proprement dite, vous avez besoin d'un framework MVC.

Les exemples de jQuery Mobile sont aussi principalement destinés à la création de sites Web mobiles qui, puisqu'ils récupèrent les pages d'un serveur, supposent que la réutilisation du code se fait côté serveur. Une application phonegap est une toute autre chose puisque vous allez générer ces pages à la volée ou à partir de fichiers statiques locaux. C'est là que le framework MVC entre en jeu, car vous allez construire vos pages en utilisant des contrôleurs, des vues, des aides de vue et des classes de modèle. Vous reliez tout cela à jQuery mobile en écoutant l'événement pagebeforeshow, comme indiqué sur la page de documentation jQm à l'adresse suivante pages de script

2voto

frequent Points 8657

Cela dépend de la façon dont vous chargez les pages respectives.

Si vous utilisez rel="external" - pas d'AJAX, chaque page sera entièrement rechargée.

Si vous utilisez JQM - AJAX normal, JQM saisira la page et l'attachera à votre DOM existant. Considérez votre première page comme votre page "d'ancrage", à laquelle toutes les pages suivantes sont ajoutées/supprimées.

Dans le deuxième cas, vous pouvez spécifier un attribut data-append-to-all-pages="true" sur les éléments que vous souhaitez voir apparaître sur chaque page.

Ensuite, il suffit d'écouter l'événement correspondant (pagebeforeshow ?) et d'ajouter des éléments avec l'étiquette ci-dessus à la nouvelle page avant qu'elle ne soit affichée. De cette façon, il suffirait de définir les éléments sur la première page, puis de les ajouter automatiquement à toute page suivante qui serait aspirée et ajoutée au DOM.

Je me penche actuellement sur ce problème avec un formulaire de connexion, dont j'ai besoin sur toutes les pages autres que celle de la connexion, et je dois éviter de me retrouver avec des doublons dans l'input#someID.

EDIT - solution possible

Placez l'élément correspondant sur la première page et ajoutez des attributs uniques, comme suit :

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

Toutes les autres pages ne reçoivent que l'élément unique conteneur

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

Ensuite, utilisez ce 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();
            }
         });
     }); 

Bien sûr, cela signifie que vous devez avoir le conteneur unique sur chaque page. Mais alors vous ne feriez que transporter le contenu de celui-ci au fur et à mesure que vous vous déplacez dans l'application. Cela devrait fonctionner pour moi et éviter d'avoir le même formulaire de connexion 2+ fois dans le DOM.

De plus, vous seriez libre d'en modifier le contenu, par exemple en ajoutant une classe active.

2voto

imaginethepoet Points 675

Nous n'avons pas encore trouvé un bon moyen de le faire non plus. Nous gérons donc cela dynamiquement dans notre fichier js personnalisé. Nous recherchons le conteneur de fermeture, puis nous ajoutons dynamiquement le pied de page après la fermeture de la dernière division de contenu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X