Vorwort
Bubble-Komponenten kommen in der tatsächlichen Arbeit sehr häufig vor, sei es in Webseiten oder Apps, wie zum Beispiel:
Die sogenannte Bubble-Komponente bezieht sich hier auf die DOM-Implementierung, die CSS-Implementierung und die JS-Implementierung. Abschließend werden wir einige Details erklären >
Xiaochai ist seit kurzem neu bei CSS. Hier ist ein spezielles Thema, um ihr eigenes CSS zu verbessern. Bitte geben Sie mir Ihre AnleitungKomponentenklassifizierung
Was die Blasenkomponente betrifft, gehört sie immer noch zur Komponente vom Typ „Popup-Ebene“, was bedeutet, dass sie die folgenden Eigenschaften aufweist:① Layout ist außerhalb des Dokumentenflusses
② Sie können eine Maske haben und konfigurieren, ob die Klickmaske deaktiviert ist
③ Zu den optionalen Funktionen gehören das Zurückklicken im Browser, um die Komponente zu schließen, und die Animationsfunktionen zum Anzeigen und Ausblenden von Animationen
Die unterschiedlicheren sind:
① Nicht zentriert
② hat eine Pfeilmarkierung und kann nach oben oder unten eingestellt werden
③ Da es einen Pfeil gibt und dieser Pfeil relativ zu einem Element ist, ist unsere Aufgabe im Allgemeinen relativ zu einer Schaltfläche, daher spricht man von einem TriggerEL
Basierend auf der Diskussion hier heißt unsere Komponente BubbleLayer, die von einem allgemeinen Layer erben sollte
Was Layer betrifft, wird es jedoch mindestens die folgenden allgemeinen Eigenschaften aufweisen:
① Erstellen – erstellen
② Anzeigen——zeigen
③ Ausblenden – ausblenden
④ Zerstören – zerstören
Die oben genannten Funktionen gelten nicht nur für die Layer-Komponente, sondern für alle Komponenten. Daher sollte über dem Layer eine abstrakte Komponente von AbstractView vorhanden sein
Die Vererbungsbeziehung ist nun offengelegt, abgesehen von den redundanten Schnittstellen, sie ist einfach wie folgt:
Die einfachste Implementierung auf Komponenten-DOM-Ebene
Aus Sicht der DOM-Implementierung kann ein einfacher UL die Aufgabe tatsächlich erledigen这个时候在为其加一个伪类,做点样式上的调整,便基本实现了,这里用到了伪类的知识点:
http://sandbox.runjs.cn/show/9ywitfn8
Mängel und ErweiterungenAls grundlegende Implementierung stellt das oben Gesagte kein Problem dar, die tatsächlichen Anwendungsszenarien weisen jedoch die folgenden Mängel auf:
① Die grundlegende UL-Ebene erfordert eine Umhüllungsschicht. Die Umhüllungsschicht hat eine Aufwärts- oder Abwärtsklasse und bestimmt dann, ob der Pfeil nach oben oder unten zeigt
② Wir können hier keine Pseudoklassen verwenden. Der Grund dafür ist, dass sich unser kleines Dreieck nicht unbedingt in der Mitte befindet. Mit anderen Worten, dieses kleine Dreieck muss von js gesteuert werden Richtige Positionen. Er braucht ein Tag
Basierend auf dem oben Gesagten scheint unsere Struktur so zu sein:
① Im Stammelement können wir den aktuellen Stil nach oben oder unten
festlegen② Das i-Tag wählt basierend auf der Höhe oder Tiefe des Stammelements aus, ob es nach oben oder unten gehen soll, und das Tag kann mit js
bedient werdenZu diesem Zeitpunkt scheint die gesamte Komponente relativ vollständig zu sein, aber die tatsächliche Situation ist nicht so. Was kann ich sagen, die obige Struktur ist zu begrenzt
Diese Komponente benötigt einen Container und die Containerbezeichnung sollte sich über ul befinden. Zu diesem Zeitpunkt kann die im Container geladene DOM-Struktur nicht ul, sondern eine andere Struktur sein
Zweitens überschreiten unsere sichtbaren Elemente auf Mobiltelefonen nicht 5, auf 4S-Telefonen oft 4, daher sollten wir scrollbare Attribute wie Überlauf für den Container festlegen
Komponentenrückgabe·Endgültige StrukturAus dem oben Gesagten können wir basierend auf der Tatsache, dass es von Layer geerbt wird, eine solche Struktur bilden:
Dies kann auch die Grundstruktur unserer gesamten Popup-Layer-Klasse sein. Wir können hier viele Erweiterungen vornehmen, aber wir werden hier nicht zu sehr ins Detail gehen und nur die Blasenkomponente diskutieren
Die Struktur der Blasenkomponente ist:
Implementierung auf JS-Ebene
Dies ist immer noch der in Blade verwendete Vererbungsmechanismus. Wenn es Schüler gibt, die es nicht verstehen und interessiert sind, gehen Sie bitte zu: [Blades UI-Design] Front-End-MVC und Layering-Ideen verstehen
Über VorlagenDa das Thema unseres Abschnitts mit Refactoring zusammenhängt, liegt unser Fokus hier auf CSS. Wir generieren zunächst unsere Vorlage:
hier Es werden mehrere wichtige Anpassungspunkte angegeben:
① WrapperClass wird verwendet, um eine vom Geschäftsteam angepasste Klasse hinzuzufügen, um die Klasse des Stammelements zu ändern. Der Vorteil davon besteht darin, dass das Geschäftsteam den Stil der Blasenkomponente bequem anpassen kann
② Der anpassbare Klassenname der Projektliste Ul wird lediglich angegeben, um dem Geschäftsteam die Durchführung von Stiländerungen zu erleichtern
③ Standardmäßig wird das Namensfeld des eingehenden Elements zurückgegeben, aber der Benutzer kann einen itemFn-Rückruf übergeben, um die Rückgabe anzupassen
Die obige Vorlage kann grundsätzlich die Bedingungen erfüllen. Wenn nicht, kann die gesamte Vorlage als Parameter übergeben werden
Über die js-ImplementierungAufgrund der Implementierung der Vererbung ist der Großteil unserer Arbeit bereits erledigt, wir müssen nur noch an einigen wichtigen Stellen Code schreiben
this.datamodel = {
data: [],
wrapperClass: 'cui-bubble-layer',
upClass: 'cui-pop--triangle-up',
downClass: 'cui- pop--triangle-down',
curClass: 'active',
itemStyleClass: '',
needBorder: true,
index: -1,
dir: 'up' //箭头方向默认值
};
this.events = {
'click .cui-pop-list>li': 'clickAction'
};
this.onClick = function (data, index, el, e) {
console.log(arguments);
// this.setIndex(index);
};
this.width = null;
//三角图标偏移量
this.triangleLeft = null;
this.triangleRight = null;
this.triggerEl = null;
},
initialisieren: function ($super, opts) {
$super(opts);
},
createRoot: function (html) {
this.$el = $(html).hide().attr('id', this.id);
},
clickAction: function (e) {
var el = $(e.currentTarget);
var i = el.attr('data-index');
var data = this.datamodel.data[i ];
this.onClick.call(this, data, i, el, e);
},
initElement: function () {
this.el = this.$el;
this.triangleEl = this.$('.cui-pop-triangle');
this.windowWidth = $(window) .width();
},
setIndex: function (i) {
var curClass = this.datamodel.curClass;
i = parseInt(i);
if (i < 0 || i > this.datamodel.data.length ||. i == this.datamodel.index) return;
this.datamodel.index = i;
//这里不以datamodel改变引起整个dom变化了,不划算
this.$('.cui-pop-list li').removeClass(curClass);
this.$('li[data- index="' i '"]').addClass(curClass);
},
//位置定位
reposition: function () {
if (!this.triggerEl) return;
var offset = this.triggerEl.offset();
var step = 6, w = offset .width - Schritt;
var top = 0, left = 0, right;
if (this.datamodel.dir == 'up') {
top = (offset.top offset.height 8) 'px';
} else {
top = (offset.top - this.el.offset().height - 8) 'px';
}
left = (offset.left 2) 'px';
if (offset.left (parseInt(this.width) || w) > this.windowWidth) {
this.el.css({
width: this.width || w,
top: top,
right: '2px'
});
} else {
this.el.css({
width: this.width || w,
top: top ,
left: left
});
}
if (this.triangleLeft) {
this.triangleEl.css({ 'left': this.triangleLeft, 'right': 'auto' });
}
if (this.triangleRight) {
this.triangleEl.css({ 'right': this.triangleRight, 'left': 'auto' });
}
},
addEvent: function ($super) {
$super();
this.on('onCreate', function () {
this.$el.removeClass('cui-layer');
this.$el.css({ position: 'absolute' });
});
this.on('onShow', function () {
this.setzIndexTop(this.el);
});
}
});
});
Es ist nur so, dass wir immer noch mit dem Eintreten dieses Szenarios rechnen müssen: Wenn es zu viele Projekte gibt und sie zu lang sind, müssen wir uns trotzdem darum kümmern:
Es gibt viele Möglichkeiten, damit umzugehen. Die erste besteht darin, maxHeight direkt einzugeben. Wenn die Höhe überschritten wird, wird eine Bildlaufleiste angezeigt. Die zweite besteht darin, sie dynamisch innerhalb der Komponente zu berechnen und zu überprüfen der sichtbare Bereich
Lassen Sie uns hier die Berechnung der sichtbaren Fläche verwenden, also haben wir einige Änderungen an den ursprünglichen Komponenten vorgenommen und eine Schnittstelle hinzugefügt:
Die erste Schnittstelle besteht darin, den sichtbaren Bereich zu erkennen, der vom Benutzer überschrieben werden kann
Natürlich wird es hier Arbeiten zur Ressourcenzerstörung geben, daher wird eine neue Versteckoberfläche hinzugefügt
handleSizeOverflow: function () {
if (!this.isSizeOverflow()) return;
this.listWrapper.css({
height: (parseInt(this.windowHeight * 0.8) 'px'),
overflow: 'hidden',
position: 'relative'
});
this.listEl.css({ position: 'absolute', width: '100%' });
//Die Position muss vor dem Aufruf zurückgesetzt werden
this.reposition();
this.scroll = new UIScroll({
wrapper: this.listWrapper,
scroller: this.listEl
});
},
checkSizeOverflow: function () {
this.handleSizeOverflow();
},
addEvent: function ($super) {
$super();
this.on('onCreate', function () {
this.$el.removeClass('cui-layer' );
this.$el.css({ position: 'absolute' });
});
this.on('onShow', function () {
//Überprüfen Sie, ob der sichtbare Bereich überschritten wird;
this.checkSizeOverflow();
this.setzIndexTop(this.el);
});
this.on('onHide ' , function () {
if (this.scroll) this.scroll.destroy();
});
}
An diesem Punkt ist unsere Funktion im Grunde beendet. Schließlich implementieren wir eine individuellere Funktion, um unsere Blasenkomponente in Schwarz umzuwandeln:
Fazit Die heutige Studie endet hier, da Xiaochai CSS3 als Anfänger gilt. Wenn der Artikel Fehler enthält, melden Sie ihn bitte
Seit der Animation dieser Komponente habe ich vor, die Layer-Basisklasse zu verwenden. Stattdessen werde ich die Animationstechnologie von CSS3 einführen, die hier nicht vorgestellt wird