Wasserfälle müssen schon seit einigen Jahren beliebt sein. Zuerst war es die von Pinterest ausgelöste Welle, und dann schossen Wohndesigns wie Pilze aus dem Boden, wobei viele Beispiele für Wasserfälle auftauchten, wie zum Beispiel Mogujie, Mark's (aber in letzter Zeit war es in Pornografie verwickelt, und es scheint, dass es gehänselt wurde) und „Wow“ von Taobao. Das sind großartige Beispiele, und heute werden wir über den Wasserfallfluss sprechen.
1. Absolutes Layout:
JS-Implementierungsprinzip
Tatsächlich besteht die Hauptschwierigkeit des Wasserfallstils darin, die Bilder ordentlich in den entsprechenden Spalten anzuordnen und wann mit der Aktualisierung und dem Laden der Bilder begonnen werden soll.
Die Hauptlogik und der Hauptalgorithmus zum ordentlichen Anordnen von Bildern bestehen darin, zunächst zu ermitteln, wie viele Spalten im Container platziert werden können, dann durch Berechnung die Höhe der ersten Spalte zu speichern und dann die verbleibenden Höhen zu durchlaufen (mit Ausnahme der Elemente in der). erste Spalte) und platzieren Sie diese jeweils in der Spalte mit der kleinsten Höhe. Fügen Sie einen nach dem anderen hinzu und beenden Sie schließlich den Durchlauf.
Die Einstellungen zum Starten der Aktualisierung sind sehr einfach. Die Wasserfallaktualisierung bezieht sich nur auf ein Ereignis, nämlich window.onscroll. Der Hauptalgorithmus beginnt mit dem Laden und Hinzufügen von Knoten Natürlich ist die Anzahl der hinzugefügten Knoten nicht festgelegt.
Beginnen wir mit dem Code. Der eine ist die Anordnung der Bilder, der andere ist das Festlegen der Ladeposition.
1. Bildanordnung
var $ = function() { return document.querySelectorAll.apply(document, arguments); } var arrHeight = []; //得到分列的高度 var columns = function() { //计算页面最多可以放多少列 var containerW = $("#main")[0].clientWidth, pinW = $(".pin")[0].offsetWidth; return Math.floor(containerW / pinW); } var getIndex = function(arr) { //获得最小高度的index var minHeight = Math.min.apply(null, arr); //获得最小高度 for (var i in arr) { if (arr[i] === minHeight) { return i; } } } //根据列数确定第一排img的高度并放入数组当中。 var setCenter = (function() { //通过列数设置宽度 var main = $('#main')[0]; //获得罩层 var getPadding = function() { //设置padding var col = columns(); //获得最后一列 var padding = main.clientWidth - col * $('.pin')[0].offsetWidth; return padding / 2; } var getComputedStyle = function(ele) { //兼容IE的支持情况 if (window.getComputedStyle) { return window.getComputedStyle(ele); } else { return ele.currentStyle; } } var getPinPad = function() { //获得pin的padding值 var pin = $(".pin")[0]; return parseInt(getComputedStyle(pin).paddingLeft); } return function() { //设置宽度 main.style.padding = `0 ${getPadding()}px 0 ${getPadding()-getPinPad()}px`; } })(); var overLoad = function(ele) { var index = getIndex(arrHeight), minHeight = Math.min.apply(null, arrHeight), //获取最小高度 pins = $('.pin'), style = ele.style; style.position = "absolute"; style.top = minHeight + "px"; //设置当前元素的高度 style.left = pins[index].offsetLeft + "px"; arrHeight[index] += ele.offsetHeight; } //初始化时执行函数 var init = function() { var pins = $(".pin"), col = columns(); setCenter(); //设置包裹容器的宽度 for (var i = 0, pin; pin = pins[i]; i++) { if (i < col) { //存储第一排的高度 arrHeight.push(pin.offsetHeight); } else { overLoad(pin); //将元素的位置重排 } } }
Es gibt insgesamt 7 Funktionen (große Funktionen) und eine Variable. Lassen Sie uns über die Idee sprechen. Zunächst einmal ist die nach dem Laden der Seite ausgeführte Funktion init. Sie müssen wissen, dass ein js-Programm seinen Eingang haben muss. Der Schlüssel hängt davon ab, wie Sie ihn finden. Dann gehen wir tief in den Init-Funktionskörper hinein und beobachten. Die in init ausgeführte Geschäftslogik besteht darin, die Höhe der ersten Elementreihe zu speichern und dann die verbleibenden Elemente neu anzuordnen. Verwenden Sie die Spaltenfunktion, um die maximale Anzahl von Spalten zu ermitteln, die im aktuellen Fenster platziert werden können, und legen Sie dann die Mitte des Containers fest (legen Sie sie einfach durch Auffüllen fest). Durchqueren Sie dann das Zellenfeld des Pins und speichern Sie die Höhe des ersten Reihe von Elementen im arrHeight-Array und fügen Sie die restlichen Elemente hinzu. Die folgenden Elemente werden neu angeordnet. Andere Funktionen müssen nicht erklärt werden. Konzentrieren wir uns auf die OverLoad-Funktion.
2. Überlastung
var overLoad = function(ele) { var index = getIndex(arrHeight), minHeight = Math.min.apply(null, arrHeight), //获取最小高度 pins = $('.pin'), style = ele.style; style.position = "absolute"; style.top = minHeight + "px"; //设置当前元素的高度 style.left = pins[index].offsetLeft + "px"; arrHeight[index] += ele.offsetHeight; }
In overLoad gibt es eine getIndex-Funktion, um den Index der minimalen Höhe abzurufen. Anschließend können Sie die Position des eingehenden Elements festlegen (absolute Positionierung oben ist der px-Wert der minimalen Höhe im Array). left wird für die erste Zeile festgelegt. Die linke Randposition des Indexelements. Aktualisiere endlich die Höhe, ok!!! das reicht.
3. Legen Sie den Ladeort fest
var dataInt = [{ 'src': '1.jpg' }, { 'src': '2.jpg' }, { 'src': '3.jpg' }, { 'src': '4.jpg' }, { 'src': '1.jpg' }, { 'src': '2.jpg' }, { 'src': '3.jpg' }, { 'src': '4.jpg' }]; function isLoad() { //是否可以进行加载 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop, wholeHeight = document.documentElement.clientHeight || document.body.clientHeight, point = scrollTop + wholeHeight; //页面底部距离header的距离 var arr = $('.pin'); var lastHei = arr[arr.length - 1].getBoundingClientRect().top; return (lastHei < point) ? true : false; } //处理滑动 var dealScroll = (function() { var main = $('#main')[0], flag = true; return function() { if (isLoad() && flag) { for (var i = 0, data; data = dataInt[i++];) { var div = document.createElement('div'); div.innerHTML = temp(data.src); div.className = "pin"; main.appendChild(div); overLoad(div); //和上面的overload有耦合性质 } flag = false; setTimeout(function() { //控制滑行手速,时间越长对速度的滑动时间影响越大。 flag = true; }, 200); } } })(); function temp(src) { return ` <div class="box"> <img src="http://cued.xunlei.com/demos/publ/img/P_00${src}"/> </div> `; }
Eigentlich ist dies nur ein Mittel zum Laden von Daten (manueller Auslöser) oder andere Lademethoden. Wie Sie es einrichten, liegt natürlich ganz bei Ihnen. Folgen Sie daher dem Trend und scrollen Sie trotzdem nach unten, um zu laden. Fahren Sie fort und suchen Sie den Eintrag function->dealScroll. Die Aufgabe dieser Funktion besteht darin, zu bestimmen, ob das Laden über die Funktion isload durchgeführt werden kann. Werfen wir einen Blick auf die Isload-Funktion. Dies ist der entscheidende Punkt beim rollierenden Laden.
function isLoad() { //是否可以进行加载 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop, wholeHeight = document.documentElement.clientHeight || document.body.clientHeight, point = scrollTop + wholeHeight; //页面底部距离header的距离 var arr = $('.pin'); var lastHei = arr[arr.length - 1].getBoundingClientRect().top; return (lastHei < point) ? true : false; }
Durch Berechnung wird die Position des unteren Randes der Seite im Ansichtsfenster (unterer Teil der Symbolleiste) mit der absoluten Position des letzten Elements verglichen. Wenn der Schiebeabstand überschritten wird, wird das Laden aktiviert.
ja~ Das ist vorbei.
zurück zu DealScroll
Der nächste Schritt besteht darin, sich den Ladeteil anzusehen. Zu diesem Teil gibt es eigentlich nichts zu sagen. Er besteht darin, einen Div-Knoten zu erstellen, ihn dann am Ende des Containers zu platzieren und die Position des zu verwalten Knoten. Außerdem habe ich am Ende der Funktion einen Trick eingerichtet, um die Gleitgeschwindigkeit zu steuern. Durch die Drosselung der Funktion kann ich verhindern, dass die Anfrage zu langsam ist und der Benutzer wiederholt Anfragen sendet, was zu einer Verschwendung von Ressourcen führt.
Dann kann dieser Teil zu Ende gehen.
4. Reaktionsfreudig
Der letzte Teil ist die Reaktionsfähigkeit. Auch dieser Teil ist super einfach. Solange Sie die Kapselung gut durchführen, wird in diesem Teil lediglich ein Größenänderungsereignis hinzugefügt. Suchen wir weiter nach der Eingabefunktion.
var resize = (function() { var flag; return function(fn) { clearTimeout(flag); flag = setTimeout(function() { //函数的节流,防止用户过度移动 fn(); console.log("ok") }, 500); } })();
In ähnlicher Weise wird hier die Idee der Funktionsdrosselung verwendet. Als Programmierer sollten Sie niemals denken, dass Benutzer nichts Dummes tun können. Ziehen Sie beispielsweise das Browserfenster nach unten abspielen, hineinzoomen, herauszoomen und dann vergrößern ... Tatsächlich mache ich das oft, weil ich keine Freundin habe und es mir langweilig wird, Code zu schreiben, also ziehe ich einfach den Browser, um abzuspielen. Daher ist es angesichts der Bedürfnisse unseres Einzelhundes unbedingt erforderlich, eine Funktionsdrosselung einzusetzen. Wenn Sie sich für Kinderschuhe interessieren, können Sie meinen vorherigen Artikel lesen, um mehr zu erfahren. Zur Erläuterung: Die Rückruffunktion bezieht sich hier auf die Init-Funktion, es müssen jedoch einige Änderungen an Init vorgenommen werden. Siehe Details.
var update = function(ele) { //当resize的时候,重新设置 ele.style.position = "initial"; } //初始化时执行函数 var init = function() { var pins = $(".pin"), col = columns(); arrHeight = []; //清空高度 setCenter(); //设置包裹容器的宽度 for (var i = 0, pin; pin = pins[i]; i++) { if (i < col) { //存储第一排的高度 arrHeight.push(pin.offsetHeight); update(pin); } else { overLoad(pin); //将元素的位置重排 } } }
Das Update muss oben hinzugefügt werden, um die neue erste Reihe von Elementen zu aktualisieren.
Dann können Sie es einfach umstellen und verwenden.
Dies ist definitiv der größte Teil des Layouts. Eine weitere Layoutmethode des JavaScript-Wasserfallflusses finden Sie im nächsten Artikel „Detaillierte Erläuterung der JavaScript-Implementierung des Wasserfallflusslayouts“ .