Implementierung von Wasserfall-Layout + dynamischem Rendering

Implementierung von Wasserfall-Layout + dynamischem Rendering

Typische Wasserfall-Website

Huaban.com, Duitang

Wasserfall-Flow-Layout-Prinzip

Allgemeine Idee

Zunächst einmal sind die Seitenlayout-Merkmale: gleiche Breite, unterschiedliche Längen

Daraus können wir erkennen, dass diese Art der Anordnung die Idee der absoluten Positionierung erfordert.

Die fünf oben sind normal angeordnet, und nach dem sechsten müssen Sie den kürzesten finden, der hinzugefügt werden soll.

Wie erhält man die kürzeste Spalte?

Die erste ist am einfachsten zu finden. Sie können die Höhe der anderen Boxen ermitteln, die kürzeste Box finden und dann die Position der kürzesten Box ermitteln.

Die Positionierung der neu hinzugefügten Box ist:

  • links: der Index der kürzesten Box * (Boxbreite + linker und rechter Abstand)
  • oben: die Höhe dieser Box + oberer und unterer Abstand

Nach dem Einsetzen wird die Höhenänderung dieser Säule erfasst, um eine neue Höhe zu generieren und anschließend die nächste Runde des Höhenvergleichs durchzuführen. Und so weiter.

waterful ist eine auf jquery basierende Komponente.

Konkrete Ideen

Links und rechts der äußersten Kanten ist kein Abstand vorhanden, bei 5 Spalten sind es also 4 Abstände. Wenn die width konstant ist, kann die Breite des space wie folgt berechnet werden:

Abstand

var Leerzeichen = (wParent – ​​5 * Breite) / (Spalte – 1);
// wParent ist die Breite der übergeordneten Box, width ist die Breite der untergeordneten Box, col ist die Anzahl der Spalten

Positionierung der Boxen in der ersten Reihe:

  • oben: 0
  • links: Index * (Breite + Leerzeichen)

Positionierung der Boxen in der zweiten Reihe:

  • oben: min. Höhe + Leerzeichen
  • links: Index * (Breite + Leerzeichen)

Daher sollte die Höhe 5 Spalten durch ein Array dargestellt werden und das kürzeste Element und sein aktueller Index können gefunden werden.

Plugin-Verpackung

Weil sowohl für die erste als auch n Ladung ein Wasserfalllayout erforderlich ist. Daher kann die Kapselung der Wasserfall-Flow-Layoutmethode in ein Plug-In eine Code-Wiederverwendung ermöglichen. Verstehen Sie zunächst das html -Layout des Wasserfallflusses

<!--Seitencontainer-->
<div Klasse = "Container">
      <!--Die Sammlung aller Elemente, mit einem Abstand vom oberen Rand-->
      <div Klasse = "Artikel">
             <!--Jeder kleine Block enthält Bilder und Text-->
              <div Klasse = "Artikel">
                    <img src = "" />
                    <p>Hallo</p>
              </div>

              <div Klasse = "Artikel">
                    <img src = "" />
                    <p>Hallo</p>
              </div>
      </div>
</div>
<div Klasse = "btn">Wird geladen...</div>

Lassen Sie uns ein jquery Plugin kapseln

erster Schritt

Konvertieren Sie globale Variablen in jquery in lokale Variablen.

Verhindern Sie globale Verschmutzung und verbessern Sie die Leistung, indem Sie einen Abschluss bilden. Die im Abschluss definierten Variablen wirken sich nicht auf externe Variablen aus.

/*Selbstaufruf bildet einen Abschluss*/
(Funktion($){
/*Wenn Sie jQuery nicht hinzufügen, ist das verwendete $ eine globale Variable, und nach dem Hinzufügen wird die Mitgliedsvariable verwendet*/

})(jQuery);

Schritt 2

jquery.fn.extend(Objekt)

fn -Funktion in jquery

Stellt einen Einstiegspunkt für eine Methode eines Drittanbieters bereit und erweitert den jquery Elementsatz (Elemente, die mit $ abgerufen werden können), um neue Methoden bereitzustellen (normalerweise zum Erstellen von Plug-Ins verwendet).

/*js/jquery-waterfall.js*/
(Funktion($){
     $.fn.waterfall = Funktion(){
        /*Dies bezieht sich auf den Elementsatz, der diese Methode aktuell aufruft (der Elementsatz ist ein von jQuery erhaltenes Pseudoarray)*/
         konsole.log(dies);
     }
})(jQuery);

Schritt 3

Ordnen Sie die erste Reihe an

(Funktion($){
    $.fn.waterfall = Funktion(){
    // dies bezieht sich auf den Elementsatz, der diese Methode aktuell aufruft // Der aktuelle übergeordnete Wasserfallcontainer var items = $(this);
        //Breite des übergeordneten Containers var wParent = items.width();
        //Aktueller Wasserfall-Untercontainer var child = items.children();
        //Breite des untergeordneten Containers abrufen var width = child.width();
        //Annehmen, wie viele Spalten es gibt var col = 5;
        //Berechnen Sie den Abstand (Breite des übergeordneten Elements minus Breite aller Felder / 4)
        var Leerzeichen = (wParent - Spalte * Breite) / (Spalte - 1);

        //Array, das die Höhe jeder Spalte aufzeichnet, var colHeightArr = [];

        //Jedes untergeordnete Element durchlaufen$.each(child,function(i,item){
            var $item = $(item);
            var Höhe = $item.height();

            //Positionierung festlegen //Die Elemente in der ersten Zeile stehen alle oben, daher beginnt der Index bei 0, und wenn er kleiner als 5 ist, steht er oben if (i < col ) {
                $item.css({
                    oben: 0,
                    links:i * (Breite + Leerzeichen)  
                });
               //Die Höhe zum Array hinzufügen colHeightArr[i] = height;
                //Sie können auch colHeightArr.push(height); verwenden.
            }
            //Die anderen sollten nach der kürzesten Spalte sortiert werden});
    }
})(jQuery);

Jetzt können Sie den Effekt sehen (da 13 Boxen simuliert wurden, wurden die restlichen übereinander gestapelt)

Drucken Sie dieses Mal das folgende Höhenarray:

Sie können sehen, dass die Höhen der ersten 5 im Array gespeichert sind. Es kann festgestellt werden, dass die kleinste Zahl im Array 289 ist und der Index des Arrays, der 289 entspricht, der Index dieser Spalte ist.

Schritt 4

Ordnen Sie die restlichen Reihen an. Suchen Sie den kleinsten und fügen Sie ihn hinzu. Erhöhen Sie dann die Höhe dieser Spalte. Und so weiter. Die größten items entsprechen der größten Höhe. Dadurch können Sie die folgende Beladung nach unten verschieben.

(Funktion($){
    $.fn.waterfall = Funktion(){
    // dies bezieht sich auf den Elementsatz, der diese Methode aktuell aufruft // Der aktuelle übergeordnete Wasserfallcontainer var items = $(this);
        //Breite des übergeordneten Containers var wParent = items.width();
        //Aktueller Wasserfall-Untercontainer var child = items.children();
        //Breite des untergeordneten Containers abrufen var width = child.width();
        //Annehmen, wie viele Spalten es gibt var col = 5;
        //Abstand berechnen var space = (wParent - col * width) / (col - 1);

        //Array, das die Höhe jeder Spalte aufzeichnet, var colHeightArr = [];

        //Jedes untergeordnete Element durchlaufen$.each(child,function(i,item){
            var $item = $(item);
            var Höhe = $item.height();

            // Positionierung // Die Elemente der ersten Zeile stehen alle oben // Der Index beginnt bei 0, und wenn er kleiner als 5 ist, steht alles oben if (i < col ) {
                $item.css({
                    oben: 0,
                    links:i * (Breite + Leerzeichen)
                });

                //colHeightArr[i] = Höhe;
                colHeightArr.push(Höhe);
   
             //Die anderen sollen nach der kürzesten Spalte sortiert werden}else{    
                //Kürzeste Spalte zum Sortieren suchen//Index var index = 0;
                //Angenommen, die Mindesthöhe ist die Höhe, die dem ersten Index entspricht. var minHeight = colHeightArr[index];
                //Array durchlaufen und den Minimalwert und den Index finden, der dem Minimalwert entspricht //k ist der Index, v ist der Wert $.each(colHeightArr,function(k,v){
                    wenn(minHöhe > v){
                        Index = k;
                        minHöhe = v;
                    }
                });

                //Suchen Sie $item.css({
                    oben: min. Höhe + Leerzeichen,
                    links:Index * (Breite + Leerzeichen)
                })

                //Aktualisiere die Mindesthöhe im aktuellen Array auf eine neue Höhe colHeightArr[index] = minHeight + space + height;
            }
            //console.log(colHeightArr);
        });

        //Höhe des übergeordneten Containers festlegen var maxHeight = colHeightArr[0];
        $.each(colHeightArr,Funktion(k,v){
            wenn(maxHöhe < v){
                maxHöhe = v;
            }
        });
        //Maximale Höhe des übergeordneten Containers festlegen items.height(maxHeight);
    }
})(jQuery);

Effektbild:

Schritt 5

In html aufgerufen (die obigen Effektbilder wurden aufgerufen)

$(".items").Wasserfall();

Sind jedoch Bilder vorhanden, können solche Anrufe bei langsamem Netz zu Problemen führen. Wenn Sie die Bilder vor dem Laden anordnen, überlappen sich die Felder, wenn die Bilder in der Mitte geladen werden.

Lösung:

/*Nachdem alle Ressourcen auf der Seite geladen sind, wird das Layout ausgeführt. Andernfalls kann die Bildgröße nicht ermittelt und die Höhe der Box nicht erweitert werden*/
fenster.onload = funktion(){
  $(".items").Wasserfall();
}

//Warum nicht jQuery verwenden? Weil diese Methode geladen wird, nachdem das DOM-Element heruntergeladen wurde. Es ist notwendig, zu warten, bis alle Ressourcen geladen sind, bevor sie angeordnet werden./*   
$(Funktion(){
	//console.log('dom geladen');
});    
*/

Dynamisches Rendering

Da es sich um große Datenmengen handelt, erfolgt die Darstellung in Stapeln.

Schematische Darstellung:

Schnittstellendokumentation:

Schnittstellenbeschreibung: Wasserfall-Paging-Daten

Schnittstellenadresse: data.php

Anforderungsmethode: get

Schnittstellenparameter: Seite Aktuelle Seite

Seitengröße Wie viele Elemente sollen auf der aktuellen Seite angezeigt werden?

Rückgabetyp: json

Rückgabedaten:

{ Seite:2,Elemente:[{Pfad:"./Bilder/1.jpg",Text:'''},...] }

Seite Die Seitenzahl der nächsten Seite (ermittelt die Daten der nächsten Seite entsprechend der Seitenzahl)

items gibt die Daten der aktuellen Seite zurück

Pfad Bildadresse

Text

Jetzt müssen wir die Schale vorbereiten

<div Klasse="Container">
    <div Klasse="Artikel">
        <!--TODO, wo Daten gerendert werden müssen-->
    </div>
    <div class="btn loading">Wird geladen...</div>
</div>

Bedarfsanalyse

Beim Laden der ersten Seite

1. Laden Sie die Daten der ersten Seite Ajax
2. Die Schaltfläche muss als „Mehr laden“ angezeigt werden
3. Das Laden ist abgeschlossen und die Seite artTemplate wird angezeigt
4. Initialisieren Sie den Wasserfall-Layout-Wasserfall

Beim Laden der nächsten Seite

1. Daten laden

  • Manuelles Laden: Klicken Sie auf die Schaltfläche, um die nächste Datenseite zu laden
  • Automatisches Laden: Beim Scrollen nach unten wird automatisch die nächste Seite geladen

2. Die Schaltfläche muss “正在加載中...” anzeigen und kann nicht angeklickt werden, um doppelte Übermittlungen zu verhindern.
3. Der Ladevorgang ist abgeschlossen und die Seite wird angezeigt
4. Initialisieren Sie das Wasserfall-Layout
5. Die Schaltfläche muss als „Weitere Daten laden“ angezeigt werden. Wenn keine weiteren Daten vorhanden sind, deaktivieren Sie die Schaltfläche und zeigen Sie “沒有更多數據了” an.

Rendern der ersten Datenseite

Anfrage senden

Da beim Laden einer Seite das Laden von Daten, das Rendern von Seiten und das Initialisieren von Wasserfallabläufen erforderlich sind, kapseln Sie diese drei Funktionen in eine Funktion und implementieren Sie zuerst die erste Funktion:

$(Funktion(){
        //Dynamisches Wasserfall-Rendering realisieren //Rendering var render = function(){
            // Daten laden, um das Wasserfall-Layout der Seite darzustellen $.ajax({
                Typ: 'get',
                URL: „data.php“,
                Daten:{
                    //Die erste Seite page:1,
                    //10 Elemente pro Seite pageSize:10
                },
                Datentyp: „json“,
                Erfolg:Funktion(Daten){
                    konsole.log(Daten);
                }
            });
        }

        machen();
    });

Die erhaltenen Daten sind in der Abbildung dargestellt:

Rendern der Seite

Vorbereiten der Vorlage

<script Typ="text/Vorlage" id="Vorlage">
    <% für(var i=0 ; i<items.length ; i++){ %>
        <div Klasse="Artikel">
            <img src="<%=items[i].path%>" alt="">
            <p><%=items[i].text%></p>
        </div>
    <% } %>
</Skript>

<Skript>
  $(Funktion(){
    //Holen Sie sich den DOM, der bedient werden muss
    var $items = $(".items");
    var $btn = $(".btn");
    // Rendern var render = function(){
        // Daten laden, um das Wasserfall-Layout der Seite darzustellen $.ajax({
            Typ: 'get',
            URL: „data.php“,
            Daten:{
                Seite:1,
                Seitengröße:10
            },
            Datentyp: „json“,
            Erfolg:Funktion(Daten){
                konsole.log(Daten);
                $items.append(Vorlage('Vorlage',Daten));
                //Wasserfall-Layout $items.waterfall();
                //Schaltfläche ändern $btn.removeClass('loading').html('Mehr laden');
            }
        });
    }
    
    machen();
  });
</Skript>

Rendern der zweiten Seite (manuelles Laden)

Dinge, die auf der zweiten Seite geändert werden müssen:

  • Fügen Sie ein Schaltflächenklickereignis hinzu und rendern Sie es nach dem Klicken auf die Schaltfläche.
  • Wenn Sie zum Laden auf die Schaltfläche klicken, müssen Sie die Schaltfläche sperren. Andernfalls werden mehrere Ajax-Anfragen gesendet, um festzustellen, ob sich die Schaltfläche im Ladezustand befindet. Wenn dies der Fall ist, werden die Daten nicht gerendert.
  • Verwenden Sie in der Renderfunktion bei einer Änderung des Schaltflächenstatus benutzerdefinierte Eigenschaften, um die Anzahl der Seiten aufzuzeichnen, die für die nächste Seite abgerufen werden sollen. Verwenden Sie data(), übergeben Sie eine Seite darin und fügen Sie data.page darin ein. Beim Abrufen der Daten müssen Sie also den Seitenwert aus den Daten der Schaltfläche abrufen. Beim ersten Mal ist es leer, also setzen Sie einen Standardwert von 1
  • In der Renderfunktion befindet sich die Schaltfläche noch im Ladezustand, bevor die Daten erfolgreich geladen wurden. Fügen Sie daher eine Funktion „beforeSend“ mit dem Ladezustand hinzu.
  • In der Renderfunktion wird beim Rendern festgestellt, ob keine Daten vorhanden sind. Dies wird dadurch bestimmt, ob die Länge des zurückgegebenen Arrays Null ist. Wenn es Null ist, bedeutet dies, dass keine weiteren Daten vorhanden sind.
 $(Funktion(){
    //Holen Sie sich den DOM, der bedient werden muss
    var $items = $(".items");
    var $btn = $(".btn");

    // Rendern var render = function(){
        // Daten laden, um das Wasserfall-Layout der Seite darzustellen $.ajax({
            Typ: 'get',
            URL: „data.php“,
            Daten:{
                //Seitenzahl der nächsten Seite abrufen. Wenn keine Seitenzahl vorhanden ist, ist der Standardwert 1.
                Seite:$btn.data("Seite")||1,
                //10 Elemente pro Seite pageSize:10
            },
            vorSenden:Funktion(){
                $btn.addClass("loading").html('Wird geladen...');
            },
            Datentyp: 'json',
            Erfolg:Funktion(Daten){
                konsole.log(Daten);
                //Vorlage vorbereiten//Da es sich um ein Anhängen handelt, können Sie kein HTML verwenden. Sie müssen Anhängen verwenden.
                        //Der Grund für die direkte Verwendung von Daten besteht darin, dass Daten ursprünglich ein Objekt mit vielen Attributen und kein Array sind. Dies ist bei einem Array nicht möglich, da Daten nur ein Attribut haben: Länge. $items.append(template('template',data));
                //Wasserfall-Layout $items.waterfall();

                wenn (Daten.Elemente.Länge) {
                    //Schaltfläche ändern//Daten sind ein benutzerdefiniertes Attribut. Die von der Seite übertragenen Daten werden im benutzerdefinierten Attribut gespeichert.
                    $btn.data("page",data.page).removeClass('loading').html('Mehr laden');
                }anders{
                    //Keine weiteren Daten//Um festzustellen, wann keine weiteren Daten vorhanden sind, öffnen Sie das letzte Objekt, bei dem die Länge des Elemente-Arrays Null ist. $btn.addClass("loading").html("Keine weiteren Daten");
                }
            }
        });
    }

    //Schaltfläche wird geladen $btn.on('click',function(){
        // Vermeiden Sie das Senden mehrerer Ajax-Anfragen. Entscheiden Sie einfach, ob es sich im Ladezustand befindet, beenden Sie es.
        wenn($btn.hasClass("wird geladen")){
            gibt false zurück;
        }
        machen();
    })

    machen();
});

Darstellung der zweiten Seite (Scrollladen)

Beim Scroll-Rendering müssen wir die nächste Anfrage stellen, wenn die gerenderte Seite einen bestimmten Abstand vom unteren Rand des Browsers hat, was eine Beurteilung erfordert.

Schematische Darstellung:

Wenn bottom < 200px machen Sie ajax Anfrage.

Wie berechnet man bottom ?

unten = Höhe der Elemente + Abstand der Elemente vom oberen Rand - Höhe der Aufwärtskurve - Höhe des gesamten Browsers

 $(Funktion(){
    // Dynamisches Wasserfall-Rendering realisieren // Den zu bedienenden DOM abrufen
    var $items = $(".items");
    var $btn = $(".btn");

    // Rendern var render = function(){
        // Daten laden, um das Wasserfall-Layout der Seite darzustellen $.ajax({
            Typ: 'get',
            URL: „data.php“,
            Daten:{
                Seite:$btn.data("Seite")||1,   
                Seitengröße:10
            },
            vorSenden:Funktion(){
                $btn.addClass("loading").html('Wird geladen...');
            },
            Datentyp: „json“,
            Erfolg:Funktion(Daten){
                konsole.log(Daten);
                $items.append(Vorlage('Vorlage',Daten));
                //Wasserfall-Layout $items.waterfall();

                //Beurteilen, ob das Array Daten enthält if(data.items.length){
                 $btn.data("page",data.page).removeClass("loading").html('Mehr laden');
                }anders{
                    $btn.addClass("loading").html("Keine weiteren Daten");
                }
            }
        });
    }

    //Scrollen beim Laden $(window).on('scroll',function(){
        //Das Dokument muss weniger als 200 Pixel vom unteren Rand entfernt sein, damit es geladen werden kann //und der Ladevorgang kann nach Abschluss fortgesetzt werden //Die Höhe der Elemente var itemsHeight = $items.height();
        //Der Versatz der Elemente vom oberen Rand var itemsTop = $items.offset().top;
        //Der Abstand der gesamten Seite von der Oberseite des Curls var scrollTop = $(document).scrollTop();
        // Browserhöhe var winHeight = $(window).height();
        // Der Abstand zwischen der Unterseite des Browsers und der Unterseite der Elemente var bottom = itemsHeight + itemsTop - scrollTop -winHeight;
        // Bestimmen Sie, ob die Schaltfläche im Ladezustand ist. var loading = $btn.hasClass("loading");

        //Wenn die Schaltfläche kleiner als 200 ist und sich nicht im Ladezustand befindet, starte den Ladevorgang, if(bottom < 200 && !loading){
            machen();
        }
    })

    machen();
});

Probleme, die besondere Aufmerksamkeit erfordern

Bisher haben wir beim statischen Laden von Seiten window.onload verwendet, um die Seite zu rendern, nachdem alle Ressourcen auf der Seite geladen wurden. Andernfalls kommt es zu einer Seitenüberlappung.

Beim dynamischen Laden einer Seite holen wir uns zuerst die Hintergrunddaten, konvertieren sie dann in html und hängen sie an die Seite an, bevor wir mit dem Laden des img Bildes beginnen. Hier ist das gleiche Problem wie zuvor aufgetreten.

Der Grund, warum window.onload später nicht verwendet wurde, liegt darin, dass für das Originalbild bereits eine bestimmte Breite und Höhe eingestellt war. Einige img sind auf 250px eingestellt, andere auf 450px . Dies ist jedoch nicht sinnvoll, da einige Bilder dadurch verzerrt werden.

Hier sind Lösungen für das Problem:

  1. Warten Sie, bis alle Bilder geladen sind, bevor Sie die Seite rendern. Dies dauert jedoch lange und ist nicht sinnvoll.
  2. Referenz Blütenblätter

Breite und Höhe der Blütenblätter werden beim Laden von Bildern ebenfalls festgelegt, die Größe muss jedoch entsprechend der Größe des Originalbildes skaliert werden.

Die Originalgröße ist 608 und die aktuelle Breite ist 200 , daher wird die aktuelle Höhe umgewandelt

Aktuelle Höhe = 200 / 806 * 782

width ist die aktuelle Breite

//Schreiben Sie in die Template-Engine <img height = "<%=items[i].width * items[i].height / width%>" src = "<%=items[i].path%>" />
/*  
Ähnlich verhält es sich beim Ajax-Erfolg: $items.append(
    Vorlage('Vorlage',{
        Daten:Daten,
        Breite:Breite
    })
);
Auf diese Weise kann die Breitenvariable verwendet werden.
*/

Damit ist der Wasserfallfluss abgeschlossen.

Dies ist das Ende dieses Artikels über die Implementierung von Wasserfall-Layout + dynamischem Rendering. Weitere relevante Inhalte zum Wasserfall-Layout finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

<<:  Tiefes Verständnis der Verwendung von ::before/:before und ::after/:after

>>:  Ein einfaches Beispiel für die Verwendung von js, um die Zeit der letzten Woche, des letzten Monats und der letzten drei Monate abzurufen

Artikel empfehlen

So fahren Sie eine MySQL-Instanz sicher herunter

In diesem Artikel wird der Vorgang zum Herunterfa...

Einführung in HTML_PowerNode Java Academy

Was ist HTML? HTML ist eine Sprache zur Beschreib...

So erweitern Sie die Festplattengröße einer virtuellen Maschine

Nachdem Vmvare die Festplattengröße der virtuelle...

Installations-Tutorial für die komprimierte Version von MySQL 5.7.18 Archiv

In diesem Artikel wird die spezifische Methode zu...

Detaillierte Erklärung wichtiger Kaskadierungskonzepte in CSS

Kürzlich stieß ich im Verlauf des Projekts auf ei...

Tutorial zum Erstellen eines SVN-Servers mit Docker

SVN ist die Abkürzung für Subversion, ein Open-So...

Implementierung der Docker-Bereitstellung eines MySQL-Clusters

Nachteile einer Single-Node-Datenbank Große Inter...

Üben Sie die Verwendung von Golang, um mit der Docker-API zu spielen

Inhaltsverzeichnis Installieren des SDK Lokalen D...