Vorschau auf die überarbeitete Fassung Dieser Artikel wurde vor drei Tagen geschrieben. Ein älterer Kollege hat mir einige Vorschläge zur Überarbeitung gemacht und ich denke, diese Vorschläge sind tatsächlich relevant. Es gibt also diese verbesserte, modifizierte Version. Der Code wurde auf GitHub aktualisiert. Die Änderungen sind wie folgt:
Die geänderten und aktualisierten Inhalte finden Sie in den Punkten 4 und 5. Wenn Sie diesen Artikel gelesen haben, können Sie die geänderten und aktualisierten Inhalte direkt lesen. Oder Sie schauen es sich noch einmal an. Vorwort Die erste Anfrage, die ich erhielt, als ich in das zweite Unternehmen eintrat, betraf die Reparatur des Rolldeckeneffekts, der zuvor ausgelagert worden war. Ich habe mich gefragt, warum es einen Fehler in einer rollenden Decke geben sollte. Später überprüfte ich den Code und stellte fest, dass die Eigenschaft offsetTop direkt verwendet wurde und keine Kompatibilitätsverarbeitung durchgeführt wurde. offsetTop Wird verwendet, um den Abstand (Offset-Wert) vom aktuellen Element zur Oberseite des positionierten übergeordneten Elements (element.offsetParent) zu ermitteln. Die Definition der Positionierung des übergeordneten Elements „offsetParent“ lautet: das übergeordnete Element mit der Position != static, das dem aktuellen Element am nächsten ist. Möglicherweise hat die Person, die diesen Code geschrieben hat, die zusätzliche Bedingung „Positionierung des übergeordneten Elements“ nicht bemerkt. Später im Projekt stieß ich immer wieder auf den Rolldeckeneffekt, der realisiert werden musste. Jetzt werde ich eine detaillierte Einführung in die 4 mir bekannten Methoden zur Realisierung von Rolldecken geben. Kennen Sie alle vier oben genannten Methoden? Der entsprechende Code wurde auf GitHub hochgeladen. Bei Interesse können Sie den Code klonen und lokal ausführen. Bitte geben Sie einen Stern, um es zu unterstützen. Vier Implementierungsmethoden Schauen wir uns zunächst das Wirkungsdiagramm an: 1. Verwenden Sie position:sticky, um 1. Was ist Sticky Positionierung? Die klebende Positionierung entspricht der Kombination aus relativer Positionierung und fester Positionierung. Wenn der Abstand zwischen einem Element und seinem übergeordneten Element die Anforderung der klebenden Positionierung erreicht, wird der relative Positionierungseffekt des Elements zum festen Positionierungseffekt. MDN Portal 2. Wie verwenden? Nutzungsbedingungen:
Dieser Effekt kann erzielt werden, indem den Elementen, die gescrollt werden müssen, die folgenden Stile hinzugefügt werden: .klebrig { Position: -WebKit-Sticky; Position: klebrig; oben: 0; } 3. Ist dieses Attribut nützlich? Schauen wir uns zunächst die Kompatibilität dieser Eigenschaft unter „Kann ich Folgendes verwenden?“ an: Es ist ersichtlich, dass die Kompatibilität dieses Attributs nicht sehr gut ist, da diese API immer noch ein experimentelles Attribut ist. Die Kompatibilität dieser API im iOS-System ist jedoch relativ gut. Wenn wir diese API in einer Produktionsumgebung verwenden, verwenden wir sie daher normalerweise in Kombination mit den folgenden Methoden. 2. Verwenden der offset().top-Implementierung von JQuery Wir wissen, dass JQuery die API zum Bedienen von DOM und zum Lesen berechneter DOM-Attribute kapselt. Basierend auf der Kombination der API offset().top und scrollTop() können wir auch den Scrolling-Ceiling-Effekt erzielen. ... window.addEventListener('scroll', self.handleScrollOne); ... handleScrollOne: Funktion() { lass self = dies; let scrollTop = $('html').scrollTop(); let offsetTop = $('.title_box').offset().top; self.titleFixed = scrollTop > offsetTop; } ... Dies ist sicherlich möglich, aber da JQuery langsam aus dem Verkehr gezogen wird, versuchen wir, die API von JQuery nicht in unserem Code zu verwenden. Wir können das native offsetTop basierend auf dem Quellcode von offset().top selbst verarbeiten. Es gibt also einen dritten Weg. scrolloTop() hat Kompatibilitätsprobleme. Im WeChat-Browser, IE und einigen Versionen von Firefox ist der Wert von $('html').scrollTop() 0, daher gibt es eine dritte Lösung für die Kompatibilität. 3. Verwenden Sie die native offsetTop-Implementierung Wir wissen, dass offsetTop der Offset des übergeordneten Elements mit relativer Positionierung ist. Wenn das zu scrollende Element als übergeordnetes Element positioniert zu sein scheint, erhält offsetTop nicht den Abstand zwischen dem Element und dem oberen Rand der Seite. Die folgenden Verarbeitungen können wir auf offsetTop selbst durchführen: getOffset: Funktion(Objekt,Richtung){ sei offsetL = 0; sei offsetT = 0; während( obj!== Fenster.Dokument.Body && obj !== null ){ offsetL += obj.offsetLeft; offsetT += obj.offsetTop; obj = obj.Parent-Offset; } wenn(Richtung === 'links'){ Rückgabewert: offsetL; }anders { Rückgabewert: offsetT; } } verwenden: ... window.addEventListener('scroll', self.handleScrollTwo); ... handleScrollTwo: Funktion() { lass self = dies; let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; let offsetTop = self.getOffset(self.$refs.pride_tab_fixed); self.titleFixed = scrollTop > offsetTop; } ... Sehen Sie Probleme bei den beiden oben genannten Methoden? Müssen wir wirklich den Wert scrollTop – offsetTop verwenden, um den Scrolltop-Effekt zu erzielen? Die Antwort ist nein. Schauen wir uns die vierte Option an. 4. Verwenden Sie obj.getBoundingClientRect().top zur Implementierung Definition: Diese API kann Ihnen den Abstand eines Elements auf der Seite relativ zum Browserfenster mitteilen. Verwendung: Die Tab-Obergrenze kann obj.getBoundingClientRect().top anstelle von scrollTop - offsetTop verwenden, der Code lautet wie folgt: //html <div Klasse="Stolz_Tab_fixiert" ref="Stolz_Tab_fixiert"> <div Klasse = "Pride_tab": Klasse = "titleFixed == true? 'isFixed':''"> //etwas Code </div> </div> // vue Standard exportieren { Daten(){ zurückkehren { Titel behoben: false } }, aktiviert(){ this.titleFixed = falsch; window.addEventListener('scroll', this.handleScroll); }, Methoden: { //Scrollen überwachen, Kopf fixiert handleScroll: function () { Lassen Sie offsetTop = this.$refs.pride_tab_fixed.getBoundingClientRect().top; this.titleFixed = offsetTop < 0; //etwas Code } } } Unterschied zwischen offsetTop und getBoundingClientRect() 1. getBoundingClientRect(): Wird verwendet, um die linke, obere, rechte und untere Position eines Elements auf der Seite relativ zum Browserfenster zu ermitteln. Der aufgerollte Teil des Dokuments ist nicht im Lieferumfang enthalten. Diese Funktion gibt ein Objekt mit 8 Eigenschaften zurück: oben, rechts, unten, links, Breite, Höhe, x, y 2. Offset oben: Wird verwendet, um den Abstand (Offset-Wert) vom aktuellen Element zur Oberseite des positionierten übergeordneten Elements (element.offsetParent) zu ermitteln. Die Definition der Positionierung des übergeordneten Elements „offsetParent“ lautet: das übergeordnete Element mit der Position != static, das dem aktuellen Element am nächsten ist. Die Methoden „offsetTop“ und „offsetParent“ können kombiniert werden, um den Abstand vom Element zum oberen Rand des Textkörpers zu ermitteln. Der Code lautet wie folgt: getOffset: Funktion(Objekt,Richtung){ sei offsetL = 0; sei offsetT = 0; während( obj!== Fenster.Dokument.Body && obj !== null ){ offsetL += obj.offsetLeft; offsetT += obj.offsetTop; obj = obj.Parent-Offset; } wenn(Richtung === 'links'){ Rückgabewert: offsetL; }anders { Rückgabewert: offsetT; } } Erweiterte Wissenspunkte Offsetbreite: Der Platz, den das Element horizontal einnimmt: Offsetbreite = linker Rand + linke Polsterung + Breite + rechte Polsterung + rechter Rand Offsethöhe: Der Platz, den das Element vertikal einnimmt: Offsethöhe = oberer Rand + obere Polsterung + Höhe + untere Polsterung + unterer Rand Hinweis: Wenn eine vertikale Bildlaufleiste vorhanden ist, umfasst offsetWidth auch die Breite der vertikalen Bildlaufleiste; wenn eine horizontale Bildlaufleiste vorhanden ist, umfasst offsetHeight auch die Höhe der horizontalen Bildlaufleiste; Offset oben: Der Pixelabstand zwischen der oberen Außengrenze des Elements und der oberen Innengrenze des offsetParent-Elements; OffsetLinks: Der Pixelabstand vom linken äußeren Rand des Elements zum linken inneren Rand des offsetParent-Elements; Vorsichtsmaßnahmen
Zwei aufgetretene Probleme 1. Der Moment des Deckensaugens wird von Schütteln begleitet Der Grund für das Jitter liegt darin, dass das Element, wenn seine Position fixiert wird, aus dem Dokumentfluss herausfällt und das nächste Element seinen Platz einnimmt. Es ist dieser Füllvorgang, der das Zittern verursacht. Lösung Fügen Sie diesem Deckenelement ein übergeordnetes Element gleicher Höhe hinzu. Wir überwachen den getBoundingClientRect().top-Wert dieses übergeordneten Elements, um den Deckeneffekt zu erzielen, das heißt: <div Klasse="title_box" ref="Stolz_tab_fixed"> <div Klasse = "Titel" :Klasse = "TitelFixed == true ? 'istFixed' :''"> Verwenden Sie `obj.getBoundingClientRect().top`, um Folgendes zu erreichen</div> </div> Diese Lösung kann den Jitter-Bug beheben. 2. Der Deckeneffekt kann nicht rechtzeitig reagieren Dieses Problem bereitet mir ziemliche Kopfschmerzen, ich habe ihm bisher nie Beachtung geschenkt. Erst als ich eines Tages über Meituan Essen zum Mitnehmen bestellte, begann ich, auf dieses Problem zu achten. beschreiben:
Grund: Unter iOS können Scroll-Ereignisse nicht in Echtzeit überwacht werden. Zugehörige Ereignisse werden nur ausgelöst, wenn das Scrollen stoppt. Lösung: Erinnern Sie sich an position:sticky in der ersten Lösung? Dieses Attribut weist eine gute Kompatibilität mit Systemen über IOS6 auf, sodass wir zwischen iOS- und Android-Geräten unterscheiden und zwei unterschiedliche Verarbeitungen durchführen können. iOS verwendet position:sticky und Android verwendet Scroll-Überwachung, um den Wert von getBoundingClientRect().top zu überwachen. Was ist, wenn die IOS-Version zu niedrig ist? Hier ist eine Idee: window.requestAnimationFrame(). Leistungsoptimierung (Neu) Damit ist die Einführung in die 4 Rolldeckenmethoden abgeschlossen, aber ist das wirklich das Ende? Tatsächlich besteht hier noch Optimierungspotenzial.
Problemlokalisierungsprozess Wir wissen, dass übermäßiger Reflow die Leistung der Seite beeinträchtigt. Daher müssen wir die Anzahl der Reflows so weit wie möglich reduzieren, um den Benutzern ein reibungsloseres Erlebnis zu bieten. Manche Freunde sagen vielleicht: „Das weiß ich, aber was hat das mit der Rolldecke zu tun?“ Keine Sorge, erinnern Sie sich noch daran, dass der Bildlauf nach oben offsetTop oder getBoundingClientRect().top verwendet, um den Antwort-Offset zu erhalten? Da die Attribute des Elements gelesen werden, führt dies natürlich zu einem Neufluss der Seite. Daher besteht unsere Optimierungsrichtung darin, die Anzahl der Lesevorgänge für Elementattribute zu verringern. Wenn wir uns den Code ansehen, stellen wir fest, dass, sobald ein Bildschirm-Scroll-Ereignis ausgelöst wird, die entsprechende Methode aufgerufen wird, um den Offset des Elements zu lesen. Optimierungsplan Für dieses Problem gibt es zwei Lösungen:
Die erste Option Diese Lösung ist sehr verbreitet, aber die damit verbundenen Nebenwirkungen sind auch offensichtlich, d. h. es kommt zu einer gewissen Verzögerung beim Deckeneffekt. Wenn das Produkt akzeptabel ist, ist dies eine gute Methode. Damit können Sie das Lesen nur innerhalb eines bestimmten Zeitraums steuern Die Drosselungsfunktion ist hier direkt die von lodash.js gekapselte Drosselungsmethode. Der Code lautet wie folgt: window.addEventListener('scroll', _.throttle(self.handleScrollThree, 50)); Zweite Option Die zweite Lösung ist relativ einfacher zu akzeptieren. Wenn IntersectionObserver unterstützt wird, verwenden Sie IntersectionObserver, andernfalls verwenden Sie Throttle. Lassen Sie uns zuerst über IntersectionObserver sprechen Mit IntersectionObserver kann überwacht werden, ob ein Element in den sichtbaren Bereich des Geräts eingetreten ist, ohne dass häufige Berechnungen erforderlich sind, um diese Beurteilung vorzunehmen. Mit diesem Attribut können wir das Lesen der relativen Position eines Elements vermeiden, wenn sich das Element nicht im sichtbaren Bereich befindet, und so eine Leistungsoptimierung erreichen. Wenn der Browser dieses Attribut nicht unterstützt, wird Throttle verwendet, um es zu handhaben. Mal sehen, wie kompatibel diese Eigenschaft ist: Es unterstützt mehr als 60 % und kann weiterhin in Projekten verwendet werden (Sie müssen auf gute Kompatibilität achten). Weitere Informationen zur Verwendung von IntersectionObserver finden Sie bei MDN oder im Tutorial von Ruan Yifeng. Der Code, der IntersectionObserver und Drosselklappenoptimierung verwendet, lautet wie folgt: IntersectionObserverFun: Funktion() { lass self = dies; lass ele = self.$refs.pride_tab_fixed; wenn( !IntersectionObserver ){ let Beobachter = neuer IntersectionObserver(Funktion(){ let offsetTop = ele.getBoundingClientRect().top; self.titleFixed = OffsetTop < 0; }, { Schwellenwert: [1] }); Beobachter.beobachten(document.getElementsByClassName('title_box')[0]); } anders { window.addEventListener('scrollen', _.throttle(Funktion(){ let offsetTop = ele.getBoundingClientRect().top; self.titleFixed = OffsetTop < 0; }, 50)); } }, Beachten Die IntersectionObserver-API ist asynchron und wird nicht synchron mit dem Scrollen des Zielelements ausgelöst. Die Spezifikation besagt, dass IntersectionObserver-Implementierungen requestIdleCallback() verwenden sollten. Der Rückruf wird nicht sofort ausgeführt, sondern es wird window.requestIdleCallback() aufgerufen, um die von uns angegebene Rückruffunktion asynchron auszuführen. Außerdem wird festgelegt, dass die maximale Verzögerungszeit 100 Millisekunden beträgt. Zusammenfassen: Diese Lösung, die IntersectionObserver und Throttle kombiniert, ist eine alternative Lösung. Der Vorteil dieser Lösung besteht darin, dass sie das Risiko eines Seitenneuflusses effektiv reduzieren kann, aber sie hat auch Nachteile und erfordert Einbußen bei der Laufruhe der Seite. Die konkrete Auswahl hängt von den Geschäftsanforderungen ab. Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird. |
<<: Lösung für das Problem, dass Tomcat beim normalen Zugriff auf localhost eine 404-Meldung ausgibt
>>: Analyse der Unterschiede zwischen Iframe und FRAME
Alibaba Cloud kauft Server Kaufen Sie einen Cloud...
Dadurch werden nicht nur die Kosten für die Entwic...
Nachfragehintergrund Das Projekt wurde mit Vue er...
Inhaltsverzeichnis Überblick 1. Hook-Aufrufreihen...
Ein MySQL Custom Value ist ein temporärer Contain...
【SQL】 Zusammenfassung der SQL-Paging-Abfragen Wäh...
Erstellen des Projekts Führen Sie die Befehlszeil...
Historische Befehle anzeigen und bestimmte Befehl...
Inhaltsverzeichnis 1. Häufig verwendete Zeichenfo...
Inhaltsverzeichnis Überblick Promise Race Methode...
Hintergrundanforderungen: Das ERP-System muss ein...
1. Einleitung Ich habe vor Kurzem die Prinzipien ...
Inhaltsverzeichnis 1. Quellcode 1.1 Monorepo 1.2 ...
Wenn ein Unternehmen seine Benutzerbasis vergröße...
von Nehmen wir als Beispiel den im Bild gezeigten...