42 votes

Bibliothèque de gestion de l'historique des emplacements / échange de hachage tout-en-un

Tout d'abord, je sais qu'il y a des bibliothèques qui fournissent des polyfills pour location.pushState/popState (History.js, Hash.js, jQuery hashchange), donc merci de ne pas juste un lien vers ceux-ci.

J'ai besoin d'un plus puissant de la bibliothèque pour atteindre les objectifs suivants dans une RIA:

  1. L'utilisateur clique sur un lien
  2. la bibliothèque est notifié et charges contexte via Ajax (pas de rechargement complet!)
  3. Tous <a> éléments d'un effet de levier avec un cliquez sur gestionnaire de
    • empêche la page est rechargée en 2. (preventDefault) et
    • appels location.pushState au lieu de / ensembles emplacement.de hachage pour les anciens navigateurs
  4. chargé de contenu est inséré dans la page et remplace le contenu actuel
  5. Continuer avec 1.

Aussi, précédemment chargé d'un contenu doivent être restaurés en tant que l'utilisateur navigue en arrière.

Comme un exemple, cliquez sur par le biais de Google+ dans Internet Explorer <10 et tout autre navigateur.

Est-il rien qui vient même près? J'ai besoin d'aide pour IE8, FF10, Safari 5 et Chrome 18. Aussi, elle doit avoir une licence permissive comme le MIT ou Apache.

21voto

Geert-Jan Points 5452

Je crois Sammy.js ( http://sammyjs.org) (MIT-homologué) a la meilleure mise au point sur ce que vous voulez faire, avec ses 2 piliers principaux étant:

  1. Itinéraires
  2. Les événements

Je pourrais citer les docs mais c'est assez simple:

  • installation côté client routes qui se rapportent à des choses à faire, de l'e.g: mise à jour de la vue via ajax

  • lien des événements pour appeler les itinéraires, adresse de.g: appel de la route, au-dessus lorsque je clique sur un lien. (Vous devez veiller à l'e.preventDefault est appelé dans la définition de l'événement, je crois, puisque c'est une application d'une décision vraiment, donc ça ne peut pas être captée par quoi que ce soit de la bibliothèque que vous allez utiliser à mon humble avis)

Quelques docs

Exemple d'un itinéraire: (à partir de http://sammyjs.org/docs/tutorials/json_store_1)

 this.get('#/', function(context) {
    $.ajax({
      url: 'data/items.json',
      dataType: 'json',
      success: function(items) {
        $.each(items, function(i, item) {
          context.log(item.title, '-', item.artist);
        });
      }
    });
  });

Ou quelque chose comme

 this.get('#/', function(context) {
     context.app.swap(''); ///the 'swap' here indicates a cleaning of the view
                              //before partials are loaded, effectively rerendering the entire screen. NOt doing the swap enables you to do infinite-scrolling / appending style, etc. 
     // ...
   });

Bien entendu, d'autres infoclient MVC-cadres pourraient être une option aussi, qui prennent en éloigne encore plus de la plomberie, mais peut-être exagéré dans cette situation.

un très bon (et encore assez récentes), de la comparaison:

http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/ ( J'utilise Spine.js moi-même ) .

Enfin, j'ai pensé qu'il pourrait être utile d'inclure une réponse que j'ai écrite il y a un moment qui va dans le détail à l'ensemble des meilleures pratiques (comme je le vois) côté client rafraîchit, etc. Peut-être que vous le trouverez utile:

De l'accessibilité et de tous ces frameworks JavaScript

9voto

Sujay Points 884

J'utilise actuellement PathJS dans une de mes applications. Elle a été la meilleure décision que j'ai fait. Pour votre cas d'utilisation prendre un coup d'oeil à l' Exemple HTML5.

Le morceau de code qui fait l'exemple de travail (à partir de la source):

<script type="text/javascript">
        // This example makes use of the jQuery library.

        // You can use any methods as actions in PathJS.  You can define them as I do below,
        // assign them to variables, or use anonymous functions.  The choice is yours.
        function notFound(){
            $("#output .content").html("404 Not Found");
            $("#output .content").addClass("error");
        }

        function setPageBackground(){
            $("#output .content").removeClass("error");
        }        

        // Here we define our routes.  You'll notice that I only define three routes, even
        // though there are four links.  Each route has an action assigned to it (via the 
        // `to` method, as well as an `enter` method.  The `enter` method is called before
        // the route is performed, which allows you to do any setup you need (changes classes,
        // performing AJAX calls, adding animations, etc.
        Path.map("/users").to(function(){
            $("#output .content").html("Users");
        }).enter(setPageBackground);

       Path.map("/about").to(function(){
            $("#output .content").html("About");
        }).enter(setPageBackground);

       Path.map("/contact").to(function(){
            $("#output .content").html("Contact");
        }).enter(setPageBackground);

        // The `Path.rescue()` method takes a function as an argument, and will be called when
        // a route is activated that you have not yet defined an action for.  On this example
        // page, you'll notice there is no defined route for the "Unicorns!?" link.  Since no
        // route is defined, it calls this method instead.
        Path.rescue(notFound);

        $(document).ready(function(){
            // This line is used to start the HTML5 PathJS listener.  This will modify the
            // `window.onpopstate` method accordingly, check that HTML5 is supported, and
            // fall back to hashtags if you tell it to.  Calling it with no arguments will
            // cause it to do nothing if HTML5 is not supported
            Path.history.listen();

            // If you would like it to gracefully fallback to Hashtags in the event that HTML5
            // isn't supported, just pass `true` into the method.

            // Path.history.listen(true);

            $("a").click(function(event){
                event.preventDefault();

                // To make use of the HTML5 History API, you need to tell your click events to
                // add to the history stack by calling the `Path.history.pushState` method. This
                // method is analogous to the regular `window.history.pushState` method, but
                // wraps calls to it around the PathJS dispatched.  Conveniently, you'll still have
                // access to any state data you assign to it as if you had manually set it via
                // the standard methods.
                Path.history.pushState({}, "", $(this).attr("href"));
            });
        });
    </script>

PathJS a quelques-uns des plus recherchés dispose d'une bibliothèque de routage:

  • Léger
  • Prend en charge le HTML5 Histoire de l'API, le "onhashchange " méthode", et la dégradation gracieuse
  • Prend en charge la racine des routes, des méthodes de sauvetage, paramaterized routes, route optionnelle composants dynamiques (routes), et la Programmation Orientée Aspects
  • Bien Testé (tests disponibles dans le ./répertoire tests)
  • Compatible avec tous les principaux navigateurs (Testé sur Firefox 3.6 De Firefox 4.0, Firefox 5.0, google Chrome 9, Opera 11, IE7, IE8, IE9)
  • Indépendant de toutes les bibliothèques tierces, mais joue gentil avec eux tous

J'ai trouvé la dernière trop les points les plus attractifs. Vous pouvez les trouver ici

J'espère que vous trouverez ce utile.

8voto

Mark Resølved Points 6027

je voudrais suggérer une combinaison de

crossroads.js en tant que routeur http://millermedeiros.github.com/crossroads.js/

et hasher pour la manipulation de l'historique du navigateur et le hash de l'url (w/ beaucoup de solutions de secours): https://github.com/millermedeiros/hasher/ (basé sur http://millermedeiros.github.com/js-signals/)

Ce sera encore besoin d'un peu de lignes de code (pour charger le contenu ajax etc.), mais de vous donner des charges et des tas d'autres possibilités lors de la manipulation de l'itinéraire.

Voici un exemple d'utilisation de jQuery (aucun des bibliothèques ci-dessus nécessite jQuery, je suis paresseux...)

http://fiddle.jshell.net/Fe5Kz/2/show/light

HTML

<ul id="menu">
    <li>
        <a href="foo">foo</a>            
    </li>
    <li>
        <a href="bar/baz">bar/baz</a>
    </li>
</ul>

<div id="content"></div>

JS

//register routes
crossroads.addRoute('foo', function() {
    $('#content').html('this could be ajax loaded content or whatever');
});

crossroads.addRoute('bar/{baz}', function(baz) {

    //maybe do something with the parameter ...
    //$('#content').load('ajax_url?baz='+baz, function(){
    //    $('#content').html('bar route called with parameter ' + baz);
    //});

    $('#content').html('bar route called with parameter ' + baz);
});


//setup hash handling
function parseHash(newHash, oldHash) {
    crossroads.parse(newHash);
}
hasher.initialized.add(parseHash);
hasher.changed.add(parseHash);
hasher.init();


//add click listener to menu items
$('#menu li a').on('click', function(e) {
    e.preventDefault();
    $('#menu a').removeClass('active');
    $(this).addClass('active');

    hasher.setHash($(this).attr('href'));
});​

5voto

sellmeadog Points 3431

Avez-vous regardé le BigShelf échantillon SPA (Single Page Application) à partir de Microsoft? On dirait qu'elle traite de la façon de réaliser la plupart de ce que vous demandez.

Il rend l'utilisation de History.js la coutume objet wrapper pour contrôler facilement la navigation appelé NavHistory et Knockout.js cliquer sur la manipulation.

Voici une très abrégée de flux de travail de la façon dont cela fonctionne: d'abord, vous aurez besoin d'initialiser un NavHistory objet qui encapsule history.js et enregistre un rappel qui s'exécute quand il y a une poussée de l'état ou de hachage changement:

var nav = new NavHistory({
    params: { page: 1, filter: "all", ... etc ... },
    onNavigate: function (navEntry) {
        // Respond to the incoming sort/page/filter parameters
        // by updating booksDataSource and re-querying the server
    }
});

Ensuite, vous devez définir un ou plusieurs Knockout.js les modèles de vue avec des commandes qui peuvent être liées à des liens, des boutons, etc:

var ViewModel = function (nav) {
  this.search = function () {
    nav.navigate({ page: 2, filter: '', ... }); // JSON object matching the NavHistory params
  };
}

Enfin, dans votre balisage, vous allez utiliser Knockout.js pour lier vos commandes pour les différents éléments:

<a data-bind="click: search">...</a>

Les ressources liées sont beaucoup plus détaillées dans l'explication de la façon dont tout cela fonctionne. Malheureusement, ce n'est pas un cadre unique, comme vous êtes à la recherche d', mais vous seriez surpris de voir combien il est facile d'obtenir ce travail.

Une chose de plus, à la suite de la BigShelf exemple, le site que je suis en train de construire est entièrement compatible avec tous les navigateurs, IE6+, Firefox, Safari (mobile et desktop) et Chrome (mobile et desktop).

3voto

Eliran Malka Points 6744

Plusieurs suggestions

Remarque: ExtJs l'Histoire a été étendu afin d'optimiser double (redondant) appels à l' add().

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