


Im vorherigen ArtikelVerwendung der getBoundingClientRect-Methode zum Implementieren einer einfachen Sticky-Komponente habe ich eine einfache Implementierung der Sticky-Komponente vorgestellt. Nachdem ich in den letzten zwei Tagen darüber nachgedacht hatte, stellte ich fest, dass es weitere Implementierungen gibt Der Nachteil besteht darin, dass die auf anderen Websites erzielten Effekte beim letzten Mal nicht gut waren. Basierend auf dem oben Gesagten bietet dieser Artikel eine verbesserte Version der Sticky-Komponente vollständig, ich hoffe, Sie haben Interesse am Lesen.
1. Probleme mit alten Versionen
Es gibt mehrere Probleme bei der Implementierung der vorherigen Sticky-Komponente:
Was zunächst die Wirkung von Sticky betrifft, so ändert sich vor und nach der Fixierung des Sticky-Elements nicht die Position relativ zur linken Seite des Browsers und die Gesamtbreite des Sticky-Elements die Position relativ zur Ober- oder Unterseite des Browsers und die Höhe des Sticky-Elements. In der oben bereitgestellten Implementierung werden die beiden letztgenannten sich ändernden Werte als konstante Werte betrachtet. Warum ist der obere oder untere Wert immer 0, wenn er fest ist? Natürlich kann es auch ein anderer Wert als 0 sein, z. B. oben: 20 Pixel, unten: 15 Pixel. In einigen Szenen führt das Hinzufügen einiger solcher Offsets dazu, dass der Sticky-Effekt besser aussieht, z Komponente Die Funktion ähnelt der in diesem Artikel implementierten Sticky-Komponente):
Die Position relativ zum oberen Rand des Browsers wird auf „top: 20px“ festgelegt, wenn dies behoben ist. Das Gleiche gilt für die Höhe klebriger Elemente, um im fixierten Zustand einen besser aussehenden Effekt zu erzielen. Es ist auch eine sehr häufige Anforderung, die ursprüngliche Linienhöhe oder den oberen Rand sowie andere höhenbezogene Attribute anzupassen. Auf dieser Seite von Tmall Huabei verwendet dieser Blockinhalt die Sticky-Komponente:
Vor dem Fixieren beträgt die Höhe des Klebeelements:
Nach der Fixierung beträgt die Höhe des Klebeelements:
Zweitens besteht die oben bereitgestellte Implementierung beim Aufheben der Fixierung am Beispiel des oben fixierten Sticky-Elements darin, die Position des Sticky-Elements direkt abzubrechen, wenn der Abstand zwischen dem Zielelement und der Oberseite des Browsers gleich ist kleiner als stickyHeight: festes Attribut, das Sticky-Element wird sofort in den normalen Dokumentfluss zurückgesetzt und der Effekt ist:
Es verschwindet sofort, wenn es den kritischen Punkt erreicht, aber die Wirkung von Tmall Huabei ist nicht so:
Es verschwindet nicht sofort, wenn es den kritischen Punkt erreicht, sondern passt den oberen Wert des Sticky-Elements neu an, sodass es in Verbindung mit der Bildlaufleiste zusammen mit dem Hauptinhalt der Webseite nach oben scrollen kann:
Aus Erfahrungssicht ist es offensichtlich, dass die Wirkung von Tmall Huabei besser ist. Aus funktionaler Sicht weist die oben bereitgestellte Implementierung einen schwerwiegenden Mangel auf: Wenn die Höhe des klebrigen Elements sehr groß ist Übersteigt die Fähigkeiten des Browsers. Wenn Sie die Höhe des Bereichs anzeigen, tritt ein Fehler auf, der dazu führt, dass Sie nicht alle Inhalte der Sticky-Elemente durchsuchen können. Wenn Sie interessiert sind, können Sie den zuletzt implementierten Code ausprobieren die Seitenleiste Ihres Blogs. Ich habe dieses Problem ausprobiert und festgestellt, deshalb wollte ich die klebrige Komponente verbessern: (
Drittens weist die letzte Implementierung noch einige Mängel auf:
1) documentElement.clientHeight wird nicht zwischengespeichert, was dazu führt, dass es jedes Mal neu erfasst wird, wenn der kritische Punkt beurteilt wird:
2) Der Standardwert des Scroll-Callback-Intervalls ist zu groß und sollte kleiner eingestellt werden. Diesmal beträgt er 5 und Bootstrap verwendet 1. Nur so kann ein reibungsloser Effekt gewährleistet werden
4) Wenn das Sticky-Element fixiert und nicht fixiert ist, sollte eine Rückruffunktion bereitgestellt werden, damit andere Komponenten an wichtigen Punkten Dinge tun können, wenn sie von dieser Komponente abhängig sind.
2. Wie man sich verbessert
Die Komponentenoptionen wurden neu definiert:
var DEFAULTS = { target: '', //target元素的jq选择器 type: 'top', //固定的位置,top | bottom,默认为top,表示固定在顶部 wait: 5, //scroll事件回调的间隔 stickyOffset: 0, //固定时距离浏览器可视区顶部或底部的偏移,用来设置top跟bottom属性的值,默认为0 isFixedWidth: true, //sticky元素宽度是否固定,默认为true,如果是自适应的宽度,需设置为false getStickyWidth: undefined, //用来获取sticky元素宽度的回调,在不传该参数的情况下,stickyWidth将设置为sticky元素的offsetWidth unStickyDistance: undefined, //该参数决定sticky元素何时进入dynamicSticky状态 onSticky: undefined, ///sticky元素固定时的回调 onUnSticky: undefined ///sticky元素取消固定时的回调 };
Die fett gedruckten Werte sind neu oder geändert. Die ursprüngliche Höhe wurde entfernt und durch unStickyDistance ersetzt. Beim Fixieren wird die Position relativ zum oberen oder unteren Rand des Browsers mit stickyOffset angegeben, sodass der obere oder untere Attributwert nicht in das CSS von .sticky--in-top oder .sticky--in geschrieben werden muss -unten. Wenn isFixedWidth false ist, wird ein Rückruf zum Aktualisieren der Breite des Sticky-Elements während der Größenänderung hinzugefügt:
!opts.isFixedWidth && $win.resize(throttle(function () { setStickyWidth(); $elem.hasClass(className) && $elem.css('width', stickyWidth); sticky(); }, opts.wait));
Im Vergleich zum letzten Mal besteht das Problem bei dieser Implementierung in der logischen Verarbeitung beim Abbrechen der Fixierung. Beim letzten Mal gab es nur zwei Zustände: „klebrig“ und „nicht klebrig“. staticSticky und DynamicSticky. Ersteres stellt den klebrigen Zustand dar, in dem der obere oder untere Wert unverändert bleibt. Letzteres entspricht tatsächlich dem Bereich, in dem die Fixierung erfolgt Um dieses Problem klarer zu lösen, lautet das ursprüngliche Urteil: Die kritischen Punkte und der Code, der an verschiedenen kritischen Punkten unterschiedliche Verarbeitungen durchführt, werden wie folgt umstrukturiert:
setSticky = function () { !$elem.hasClass(className) && $elem.addClass(className).css('width', stickyWidth) && (typeof opts.onSticky == 'function' && opts.onSticky($elem, $target)); return true; }, states = { staticSticky: function () { setSticky() && $elem.css(opts.type, opts.stickyOffset); }, dynamicSticky: function (rect) { setSticky() && $elem.css(opts.type, rules[opts.type].getDynamicOffset(rect)); }, unSticky: function () { $elem.hasClass(className) && $elem.removeClass(className).css('width', '').css(opts.type, '') && (typeof opts.onUnSticky == 'function' && opts.onUnSticky($elem, $target)); } }, rules = { top: { getState: function (rect) { if (rect.top < 0 && (rect.bottom - unStickyDistance) > 0) return 'staticSticky'; else if ((rect.bottom - unStickyDistance) <= 0 && rect.bottom > 0) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance - rect.bottom); } }, bottom: { getState: function (rect) { if (rect.bottom > docClientHeight && (rect.top + unStickyDistance) < docClientHeight) return 'staticSticky'; else if ((rect.top + unStickyDistance) >= docClientHeight && rect.top < docClientHeight) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance + rect.top - docClientHeight); } } } $win.scroll(throttle(sticky, opts.wait)); function sticky() { var rect = $target[0].getBoundingClientRect(), curState = rules[opts.type].getState(rect); states[curState](rect); }
Es enthält ein wenig die Idee des Staatsmodells, ist aber prägnanter. Als ich diesen Code schrieb, wollte ich unbedingt die Zustandsmaschine verwenden, die ich zuvor kennengelernt hatte, aber ich wollte nur verhindern, dass auf eine Klassenbibliothek verwiesen wird Versuchen Sie es eines Tages noch einmal, wenn Sie Zustandsautomaten üben möchten.
Die Gesamtimplementierung ist wie folgt:
var Sticky = (function ($) { function throttle(func, wait) { var timer = null; return function () { var self = this, args = arguments; if (timer) clearTimeout(timer); timer = setTimeout(function () { return typeof func === 'function' && func.apply(self, args); }, wait); } } var DEFAULTS = { target: '', //target元素的jq选择器 type: 'top', //固定的位置,top | bottom,默认为top,表示固定在顶部 wait: 5, //scroll事件回调的间隔 stickyOffset: 0, //固定时距离浏览器可视区顶部或底部的偏移,用来设置top跟bottom属性的值,默认为0 isFixedWidth: true, //sticky元素宽度是否固定,默认为true,如果是自适应的宽度,需设置为false getStickyWidth: undefined, //用来获取sticky元素宽度的回调,在不传该参数的情况下,stickyWidth将设置为sticky元素的offsetWidth unStickyDistance: undefined, //该参数决定sticky元素何时进入dynamicSticky状态 onSticky: undefined, ///sticky元素固定时的回调 onUnSticky: undefined ///sticky元素取消固定时的回调 }; return function (elem, opts) { var $elem = $(elem); opts = $.extend({}, DEFAULTS, opts || {}, $elem.data() || {}); var $target = $(opts.target); if (!$elem.length || !$target.length) return; var stickyWidth, setStickyWidth = function () { stickyWidth = typeof opts.getStickyWidth === 'function' && opts.getStickyWidth($elem) || $elem[0].offsetWidth; }, docClientHeight = document.documentElement.clientHeight, unStickyDistance = opts.unStickyDistance || $elem[0].offsetHeight, setSticky = function () { !$elem.hasClass(className) && $elem.addClass(className).css('width', stickyWidth) && (typeof opts.onSticky == 'function' && opts.onSticky($elem, $target)); return true; }, states = { staticSticky: function () { setSticky() && $elem.css(opts.type, opts.stickyOffset); }, dynamicSticky: function (rect) { setSticky() && $elem.css(opts.type, rules[opts.type].getDynamicOffset(rect)); }, unSticky: function () { $elem.hasClass(className) && $elem.removeClass(className).css('width', '').css(opts.type, '') && (typeof opts.onUnSticky == 'function' && opts.onUnSticky($elem, $target)); } }, rules = { top: { getState: function (rect) { if (rect.top < 0 && (rect.bottom - unStickyDistance) > 0) return 'staticSticky'; else if ((rect.bottom - unStickyDistance) <= 0 && rect.bottom > 0) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance - rect.bottom); } }, bottom: { getState: function (rect) { if (rect.bottom > docClientHeight && (rect.top + unStickyDistance) < docClientHeight) return 'staticSticky'; else if ((rect.top + unStickyDistance) >= docClientHeight && rect.top < docClientHeight) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance + rect.top - docClientHeight); } } }, className = 'sticky--in-' + opts.type, $win = $(window); setStickyWidth(); $win.scroll(throttle(sticky, opts.wait)); !opts.isFixedWidth && $win.resize(throttle(function () { setStickyWidth(); $elem.hasClass(className) && $elem.css('width', stickyWidth); sticky(); }, opts.wait)); $win.resize(throttle(function () { docClientHeight = document.documentElement.clientHeight; }, opts.wait)); function sticky() { var rect = $target[0].getBoundingClientRect(), curState = rules[opts.type].getState(rect); states[curState](rect); } } })(jQuery);
Was schwer zu verstehen ist, ist möglicherweise die Logik der getState-Methode. Einige der Ideen in diesem Teil wurden im vorherigen Blog ausführlicher erläutert.
3. Anleitung zur Blog-Seitenleiste
Zuerst müssen Sie diese Implementierung in das HTML-Textfeld für die Fußzeile der Blog-Einstellungen einfügen und dann den folgenden Code zur Initialisierung hinzufügen:
var timer = setInterval(function(){ if($('#blogCalendar').length && $('#profile_block').length && $('#sidebar_search').length) { new Sticky('#sideBar', { target: '#main', onSticky: function($elem, $target){ $target.css('min-height',$elem.outerHeight()); $elem.css('left', '65px'); }, onUnSticky: function($elem, $target){ $target.css('min-height',''); $elem.css('left', ''); } }); } },100);
Der Timer wird verwendet, da der Inhalt der Seitenleiste von Ajax geladen wird und es unmöglich ist, während dieser Ajax-Anfragen Rückrufe hinzuzufügen. Sie können nur anhand des zurückgegebenen Inhalts beurteilen, ob die Seitenleiste geladen wird.
4. Zusammenfassung
Dieses Wochenende habe ich darüber nachgedacht, wie ich die klebrige Komponente verbessern kann. Außerdem habe ich den größten Teil des Tages damit verbracht, diesen Artikel zu schreiben Es fühlte sich seltsam an, als würde etwas fehlen, aber es lag daran, dass noch so viele Dinge fehlten. Derzeit kann diese Komponente nur den Effekt des Fixierens und Aufhebens der Fixierung erzielen. Für die tatsächliche Arbeit reicht die Wirkung dieser Ebene möglicherweise nicht aus. Die im Internet üblichen Funktionen, die das Scrollen in der Navigation oder die Tab-Navigation unterstützen, sind ebenfalls sehr verbreitet. Weiter In diesem Artikel wird die Sticky-Komponente vorgestellt. Basierend auf diesem Artikel erfahren Sie, wie Sie die Komponenten navScrollSticky und tabSticky implementieren. Bleiben Sie also auf dem Laufenden.
Vielen Dank fürs Lesen :)
Zusätzliche Erklärung:
Wenn in IE und Firefox beim Aktualisieren der Seite die Seite vor dem Aktualisieren gescrollt wird, setzt der Aktualisierungsvorgang die Bildlaufposition der Seite auf die Aktualisierungsposition, das Bildlaufereignis wird jedoch nicht ausgelöst und muss daher unmittelbar danach aufgerufen werden Die Komponente wird initialisiert. Eine Sticky-Funktion:

Die Kraft des JavaScript -Frameworks liegt in der Vereinfachung der Entwicklung, der Verbesserung der Benutzererfahrung und der Anwendungsleistung. Betrachten Sie bei der Auswahl eines Frameworks: 1. Projektgröße und Komplexität, 2. Teamerfahrung, 3. Ökosystem und Community -Unterstützung.

Einführung Ich weiß, dass Sie es vielleicht seltsam finden. Was genau muss JavaScript, C und Browser tun? Sie scheinen nicht miteinander verbunden zu sein, aber tatsächlich spielen sie eine sehr wichtige Rolle in der modernen Webentwicklung. Heute werden wir die enge Verbindung zwischen diesen drei diskutieren. In diesem Artikel erfahren Sie, wie JavaScript im Browser ausgeführt wird, die Rolle von C in der Browser -Engine und wie sie zusammenarbeiten, um das Rendern und die Interaktion von Webseiten voranzutreiben. Wir alle kennen die Beziehung zwischen JavaScript und Browser. JavaScript ist die Kernsprache der Front-End-Entwicklung. Es läuft direkt im Browser und macht Webseiten lebhaft und interessant. Haben Sie sich jemals gefragt, warum Javascr

Node.js zeichnet sich bei effizienten E/A aus, vor allem bei Streams. Streams verarbeiten Daten inkrementell und vermeiden Speicherüberladung-ideal für große Dateien, Netzwerkaufgaben und Echtzeitanwendungen. Die Kombination von Streams mit der TypeScript -Sicherheit erzeugt eine POWE

Die Unterschiede in der Leistung und der Effizienz zwischen Python und JavaScript spiegeln sich hauptsächlich in: 1 wider: 1) Als interpretierter Sprache läuft Python langsam, weist jedoch eine hohe Entwicklungseffizienz auf und ist für eine schnelle Prototypentwicklung geeignet. 2) JavaScript ist auf einen einzelnen Thread im Browser beschränkt, aber Multi-Threading- und Asynchronen-E/A können verwendet werden, um die Leistung in Node.js zu verbessern, und beide haben Vorteile in tatsächlichen Projekten.

JavaScript stammt aus dem Jahr 1995 und wurde von Brandon Ike erstellt und realisierte die Sprache in C. 1.C-Sprache bietet Programmierfunktionen auf hoher Leistung und Systemebene für JavaScript. 2. Die Speicherverwaltung und die Leistungsoptimierung von JavaScript basieren auf C -Sprache. 3. Die plattformübergreifende Funktion der C-Sprache hilft JavaScript, auf verschiedenen Betriebssystemen effizient zu laufen.

JavaScript wird in Browsern und Node.js -Umgebungen ausgeführt und stützt sich auf die JavaScript -Engine, um Code zu analysieren und auszuführen. 1) abstrakter Syntaxbaum (AST) in der Parsenstufe erzeugen; 2) AST in die Kompilierungsphase in Bytecode oder Maschinencode umwandeln; 3) Führen Sie den kompilierten Code in der Ausführungsstufe aus.

Zu den zukünftigen Trends von Python und JavaScript gehören: 1. Python wird seine Position in den Bereichen wissenschaftlicher Computer und KI konsolidieren. JavaScript wird die Entwicklung der Web-Technologie fördern. Beide werden die Anwendungsszenarien in ihren jeweiligen Bereichen weiter erweitern und mehr Durchbrüche in der Leistung erzielen.

Sowohl Python als auch JavaScripts Entscheidungen in Entwicklungsumgebungen sind wichtig. 1) Die Entwicklungsumgebung von Python umfasst Pycharm, Jupyternotebook und Anaconda, die für Datenwissenschaft und schnelles Prototyping geeignet sind. 2) Die Entwicklungsumgebung von JavaScript umfasst Node.JS, VSCODE und WebPack, die für die Entwicklung von Front-End- und Back-End-Entwicklung geeignet sind. Durch die Auswahl der richtigen Tools nach den Projektbedürfnissen kann die Entwicklung der Entwicklung und die Erfolgsquote der Projekte verbessert werden.


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

WebStorm-Mac-Version
Nützliche JavaScript-Entwicklungstools

SublimeText3 Englische Version
Empfohlen: Win-Version, unterstützt Code-Eingabeaufforderungen!

EditPlus chinesische Crack-Version
Geringe Größe, Syntaxhervorhebung, unterstützt keine Code-Eingabeaufforderungsfunktion

ZendStudio 13.5.1 Mac
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Herunterladen der Mac-Version des Atom-Editors
Der beliebteste Open-Source-Editor
