Maison  >  Article  >  interface Web  >  Deux solutions pour conserver l'historique du navigateur avec Ajax

Deux solutions pour conserver l'historique du navigateur avec Ajax

巴扎黑
巴扎黑original
2017-04-29 15:44:161385parcourir

Je télécharge toujours quelque chose depuis github. Toute l'interface de github est bien conçue et l'expérience est très bonne ~ J'aime le plus l'effet spécial du glissement du code source ~ Au début, je pensais que c'était juste un effet de requête ajax ordinaire, mais je l'ai fait. a constaté que cet effet spécial peut conduire à la navigation. La barre d'adresse du navigateur suivra les modifications et vous pourrez faire glisser le code vers l'arrière et vers l'extérieur après avoir cliqué sur les boutons avant et arrière ~~ Alors étudions-le ~

1. Implémenté via le hachage du point d'ancrage :

En fait, cet aspect est utilisé depuis longtemps en Chine, comme Taobao Pictorial, qui est obtenu en ajoutant # point d'ancrage après la barre d'adresse. Le navigateur peut identifier les enregistrements historiques en unités de points d'ancrage. Mais cela ne signifie pas que la page elle-même possède ce point d'ancrage. Le hachage du point d'ancrage sert uniquement à guider le navigateur pour pousser cet enregistrement en haut de la pile d'historique.

Faisons une petite démo :

    <style type="text/css">
        #tab1_header,#tab2_header{
            cursor:pointer;
            border:1px solid;
            width:50px;
        }
        #tab1,#tab2{
            width:90%;
            height:200px;
            border:1px solid;
        }
    </style>
    <p id="tab_header">
    	<span id="tab1_header">Tab1</span>
    	<span id="tab2_header">Tab2</span>
    </p>
    <p id="tab1">1</p>
    <p id="tab2">2</p>

Un changement de tabulation très simple est généralement simple :

$("#tab1_header").click(function() {
            $("#tab2").hide();
            $("#tab1").show();
});
$("#tab2_header").click(function() {
            $("#tab1").hide();
            $("#tab2").show();
});

Mais si vous souhaitez utiliser le bouton retour pour revenir à l'onglet 1 lorsque vous cliquez sur l'onglet 2, cela ne fonctionnera pas. Si vous actualisez, le comportement du navigateur n'est pas du tout basé sur les idées de l'utilisateur. Dans ce cas, on peut ajouter. # ancre pour simuler une nouvelle page. Pourquoi dit-on Pour la simulation, si vous changez window.location directement via js, le navigateur rechargera la page, mais l'ajout de # ne la rechargera pas et pourra être enregistré dans l'historique. JS utilise window.location.hash pour contrôler le point d'ancrage # derrière l'URL.

Nous changeons le code en ceci :

$(function(){
			showTab();
			$(window).bind(&#39;hashchange&#39;, function(e){
				showTab();
			});
			$("#tab1_header").click(showTab1);
			$("#tab2_header").click(showTab2);
		});

        function showTab() {
            if (window.location.hash == "#tab2"){
				showTab2();
			} else {
				showTab1();
			}
        }
        function showTab1() {
            $("#tab2").hide();
            $("#tab1").show();
            window.location.hash = "#tab1";
        };
        function showTab2() {
            $("#tab1").hide();
            $("#tab2").show();
            window.location.hash = "#tab2";
        };

Ajoutez simplement window.location.hash = "#tab1". Après avoir cliqué sur l'onglet, #tab1 sera ajouté après la barre d'adresse. Après avoir cliqué sur tab2, il sera remplacé par #tab2 lorsque le navigateur détectera le changement d'URL lors de l'événement hashchange. est déclenché, l'événement que l'utilisateur peut obtenir en cliquant en arrière peut être jugé via window.location.hash et effectuer des opérations ajax. Cependant, l'événement haschange n'est pas disponible dans tous les navigateurs. Seuls les navigateurs avancés modernes l'ont, une interrogation est donc nécessaire. dans les navigateurs de bas niveau pour détecter si l'URL change. Cela ne sera pas abordé en détail ici.

2. Implémenté via un objet Historique amélioré HTML5 (comme Pjax)

Vous pouvez mettre à jour la barre d'adresse du navigateur sans actualiser via la méthode window.history.pushState. Cette méthode pousse l'adresse dans la pile d'historique lors de la mise à jour de la barre d'adresse. Pour supprimer la page supérieure de la pile, vous pouvez utiliser l'événement popstate pour capturer. ça ~

Simulons l'environnement github. Chaque URL dans github correspond à une page réelle complète, donc lorsque vous demandez la page avec ajax, vous devez obtenir de manière asynchrone le contenu dans le conteneur d'identifiant spécifié dans la page cible :

Par exemple, il y a deux pages comme celle-ci :

index.html

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gbk">
        <title>index</title>
    </head>
    <body>
    	<script>document.write(new Date());</script>
    	<p id="cn">
        	<a href="second.html">加载前</a>
        </p>
    </body>
</html>

seconde.html

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gbk">
        <title>second</title>
    </head>
    <body>
    	<script>document.write(new Date());</script>
        <p id="cn">
        	<a href="index.html">加载后</a>
        </p>
    </body>
</html>

S'il est ouvert avec une requête http synchrone, ce sera deux pages. Si les deux pages présentent de nombreuses similitudes, nous pouvons utiliser cette méthode pour implémenter la requête ajax pour modifier le DOM que j'ai ajouté 3f1c4e4b6b16bbbd69b2ee476dc4f83adocument.write(new. La déclaration Date());2cacc6d41bbb37262a98f745aa00fbf0 peut savoir si elle est issue de deux requêtes http grâce à ses modifications, Bureau

La requête ajax externe ne modifiera pas l’affichage de l’heure.

$(function() {
    var state = {
        title: "index",
        url: "index.html"
    };
    $("#cn").click(function() {
        window.history.pushState(state, "index", "second.html");
        var $self = $(this);
        $.ajax({
            url: "second.html",
            dataType: "html",
            complete: function(jqXHR, status, responseText) {
                responseText = jqXHR.responseText;
                if (jqXHR.isResolved()) {
                    jqXHR.done(function(r) {
                        responseText = r;
                    });
                    $self.html($("<p>").append(responseText.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")).find("#cn"));
                }
            }
        });
        document.title = "second";
        return false;
    });
    $(window).bind(&#39;popstate&#39;, function(e) {
        var st = e.state;
        //$("#cn").load(st.url + " #cn");
        $.ajax({
            url: "index.html",
            dataType: "html",
            complete: function(jqXHR, status, responseText) {
                responseText = jqXHR.responseText;
                if (jqXHR.isResolved()) {
                    jqXHR.done(function(r) {
                        responseText = r;
                    });
                    $("#cn").html($("<p>").append(responseText.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")).find("#cn"));
                }
            }
        });
        document.title = e.state.title;
    });
});

Dans l'instruction ci-dessus, lorsque l'on clique sur l'élément #cn, l'état est poussé dans la pile d'historique via la méthode pushState, et dans le troisième paramètre, la zone URL du navigateur pointe vers la deuxième page, et la deuxième page est chargée de manière asynchrone via ajax, et la partie correspondante est ajoutée au conteneur, afin de réaliser un chargement asynchrone et de modifier l'URL de la barre d'adresse. De même, lorsque l'utilisateur clique en arrière, popstate est déclenché à l'instant. dans le paramètre formel e transmis ici. Les attributs sont extraits via var st = e.state pour une utilisation en développement. En même temps, le contenu correspondant dans la page d'index est chargé. En raison du temps limité, ce js n'a pas été reconstruit, j'ai donc écrit $.ajax directement. En fait, si vous n'avez pas besoin d'effets spéciaux et que vous chargez simplement de manière asynchrone dans jQ, vous pouvez utiliser directement $("#cn"). load(st.url + " #cn ");Mettez le #cn correspondant au HTML demandé dans le conteneur #cn de cette page Cependant, si vous souhaitez ajouter des effets spéciaux plus éblouissants, vous devez directement exploiter les données renvoyées par. ajax.

$("#cn").html($("<p>").append(responseText.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")).find("#cn"));

Créez d'abord un conteneur p, chargez le code filtré par script dans ce conteneur et utilisez la méthode find pour trouver le conteneur de sélection correspondant et insérez-le dans votre propre page. Vous n'avez pas besoin de le remplir de HTML ici. Vous pouvez utiliser slideUp. selon les besoins de votre propre projet. Montrez quels effets spéciaux afficher le contenu ~~

De plus, je voudrais recommander un composant jQuery appelé pjax (https://github.com/defunkt/jquery-pjax). C'est un composant relativement génial. La partie asynchrone se charge dans une autre page correspondant au contenu du conteneur. . Le mécanisme de mise en œuvre et identique à ma deuxième option ci-dessus. pushState + ajax = pjax J'ai l'impression que cette application va devenir populaire.

Pour résumer, les deux solutions ne sont en fait pas très efficaces pour prendre en charge les navigateurs de niveau inférieur tels que IE6 ou FF3.6. La première doit utiliser l'interrogation pour surveiller le comportement de la barre d'adresse du navigateur si elle veut être compatible avec les navigateurs bas de gamme. , alors que ce dernier est Une application HTML5 complète ne peut faire des sauts de jugement que pour les navigateurs non HTML5.

  如pjax最后的一段无奈的兼容处理:  

$.support.pjax = window.history && window.history.pushState


// Fall back to normalcy for older browsers.
if ( !$.support.pjax ) {
  $.pjax = function( options ) {
    window.location = $.isFunction(options.url) ? options.url() : options.url
  }
  $.fn.pjax = function() { return this }
}

               

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn