Heim  >  Artikel  >  Web-Frontend  >  Zwei Lösungen zur Aufbewahrung des Browserverlaufs mit Ajax

Zwei Lösungen zur Aufbewahrung des Browserverlaufs mit Ajax

巴扎黑
巴扎黑Original
2017-04-29 15:44:161385Durchsuche

Ich lade immer etwas von Github herunter. Die gesamte Oberfläche von Github ist gut gemacht und die Erfahrung ist sehr gut. Am besten gefällt mir der Spezialeffekt des Quellcodes. Zuerst dachte ich, dies sei nur ein gewöhnlicher Ajax-Anforderungseffekt, aber ich Ich habe herausgefunden, dass dieser Spezialeffekt dazu führen kann, dass die Adressleiste des Browsers den Änderungen folgt, und Sie können den Code nach dem Klicken auf die Vorwärts- und Zurück-Schaltflächen hin und her schieben ~~ Schauen wir uns das also an ~

1. Implementiert durch Ankerpunkt-Hash:

Tatsächlich wird dieser Aspekt in China schon seit langem praktiziert, beispielsweise bei Taobao Pictorial, was durch das Hinzufügen eines #-Ankerpunkts nach der Adressleiste erreicht wird. Der Browser kann die historischen Datensätze in Einheiten von Ankerpunkten identifizieren. Dies bedeutet jedoch nicht, dass die Seite selbst über diesen Ankerpunkt verfügt. Der Hash des Ankerpunkts dient nur dazu, den Browser anzuleiten, diesen Datensatz an die Spitze des Verlaufsstapels zu verschieben.

Machen wir eine kleine Demo:

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

Ein sehr einfacher Tab-Wechsel ist normalerweise unkompliziert:

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

Wenn Sie jedoch die Schaltfläche „Zurück“ verwenden möchten, um zu Tab1 zurückzukehren, wenn Sie auf Tab2 klicken, funktioniert dies nicht. Wenn Sie aktualisieren, basiert das Verhalten des Browsers überhaupt nicht auf den Vorstellungen des Benutzers # Anker zum Simulieren einer neuen Seite. Warum sagen wir Zur Simulation: Wenn Sie window.location direkt über js ändern, lädt der Browser die Seite neu, aber das Hinzufügen von # lädt sie nicht neu und kann im Verlauf gespeichert werden. JS verwendet window.location.hash, um den Ankerpunkt # hinter der URL zu steuern.

Wir ändern den Code wie folgt:

$(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";
        };

Fügen Sie einfach window.location.hash = "#tab1" hinzu. Nach dem Klicken auf Tab wird #tab1 nach dem Klicken auf Tab2 hinzugefügt und beim Hashchange-Ereignis in #tab2 geändert Wird das Ereignis ausgelöst, das der Benutzer beim Zurückklicken erhalten kann, kann es über window.location.hash beurteilt und Ajax-Vorgänge ausgeführt werden. Allerdings ist das Hashchange-Ereignis nicht in jedem Browser verfügbar, daher ist es nur in modernen Browsern verfügbar Wird in Low-Level-Browsern benötigt, um zu erkennen, ob sich die URL ändert. Dies wird hier nicht im Detail besprochen.

2. Implementiert durch ein HTML5-erweitertes History-Objekt (wie Pjax)

Sie können die Adressleiste des Browsers ohne Aktualisierung über die Methode window.history.pushState aktualisieren. Diese Methode verschiebt die Adresse in den Verlaufsstapel und aktualisiert gleichzeitig die Adressleiste. Um die oberste Seite des Stapels zu entfernen, können Sie das Popstate-Ereignis verwenden es. ~

Lassen Sie uns die Github-Umgebung simulieren. Jede URL in Github entspricht einer vollständigen tatsächlichen Seite. Wenn Sie die Seite also mit Ajax anfordern, müssen Sie den Inhalt im angegebenen ID-Container auf der Zielseite asynchron abrufen:

Es gibt zum Beispiel zwei Seiten wie diese:

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>

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

Wenn es mit einer synchronen HTTP-Anfrage geöffnet wird, handelt es sich um zwei Seiten. Wenn die beiden Seiten viele Ähnlichkeiten aufweisen, können wir diese Methode verwenden, um die von mir hinzugefügte Ajax-Anfrage zu implementieren 3f1c4e4b6b16bbbd69b2ee476dc4f83adocument.write(new Die Date());2cacc6d41bbb37262a98f745aa00fbf0-Anweisung kann durch ihre Änderungen erkennen, ob sie aus zwei http-Anfragen stammt, Bureau

Die externe Ajax-Anfrage ändert die Zeitanzeige nicht.

$(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;
    });
});

Wenn in der obigen Anweisung auf das #cn-Element geklickt wird, wird der Status über die pushState-Methode in den Verlaufsstapel verschoben. Im dritten Parameter zeigt das Browser-URL-Feld auf die zweite Seite und die zweite Seite wird asynchron geladen Ajax und der entsprechende Teil werden zum Container hinzugefügt, um das asynchrone Laden zu realisieren und die URL der Adressleiste zu ändern. Wenn der Benutzer zurückklickt, wird in ähnlicher Weise der erste Parameterstatus in der pushState-Methode ausgelöst Im hier übergebenen formalen Parameter e werden Attribute über var st = e.state zur Entwicklungsverwendung entnommen. Gleichzeitig wird der entsprechende Inhalt der Indexseite geladen. Aus Zeitgründen wurde dieses js nicht rekonstruiert, daher habe ich $.ajax direkt geschrieben. Wenn Sie keine Spezialeffekte benötigen und einfach asynchron in jQ laden, können Sie $("#cn") direkt verwenden. Load(st.url + " #cn ");Fügen Sie den dem angeforderten HTML-Code entsprechenden #cn in den #cn-Container dieser Seite ein. Wenn Sie jedoch weitere schillernde Spezialeffekte hinzufügen möchten, müssen Sie die von zurückgegebenen Daten direkt verarbeiten Ajax.

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

Erstellen Sie zunächst einen p-Container, laden Sie den skriptgefilterten Code in diesen Container und verwenden Sie die Suchmethode, um den entsprechenden Auswahlcontainer zu finden und ihn in Ihre eigene Seite einzufügen. Sie können ihn hier verwenden Zeigen Sie entsprechend Ihren eigenen Projektanforderungen an, welche Spezialeffekte angezeigt werden sollen~~

Darüber hinaus möchte ich eine jQuery-Komponente namens pjax empfehlen (https://github.com/defunkt/jquery-pjax). Der asynchrone Teil wird entsprechend dem Inhalt im Container geladen . Der Implementierungsmechanismus und das Gleiche wie meine zweite Option oben. pushState + ajax = pjax Ich habe das Gefühl, dass diese Anwendung populär werden wird.

Zusammenfassend lässt sich sagen, dass die beiden Lösungen tatsächlich nicht sehr gut darin sind, Browser auf niedrigerer Ebene wie IE6 oder FF3.6 zu unterstützen. Erstere muss Polling verwenden, um das Verhalten der Browser-Adressleiste zu überwachen, wenn sie mit Low-End-Browsern kompatibel sein soll , während Letzteres der Fall ist Eine vollständige HTML5-Anwendung kann nur für Nicht-HTML5-Browser Beurteilungssprünge machen.

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

               

Das obige ist der detaillierte Inhalt vonZwei Lösungen zur Aufbewahrung des Browserverlaufs mit Ajax. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn