VorwortNach Betrachtung vieler Fälle scheint position:sticky aus einfacher Perspektive eine ideale Wahl zu sein. Wenn el-table jedoch auf fixed gesetzt ist, wird das hier festgelegte fixed ungültig. Schließlich wurde die Idee übernommen, das Scrollen durch JS zu überwachen. Umsetzungsideen
Wirkung: verwenden:Konfigurieren Sie im el-table-Tag: v-sticky="{ top: 0, parent:'#appMainDom'}", <el-Tabelle :Daten="Tabellendaten" Stil="Rand:10px 0;Breite: 100%;" bordermax-height="800" class="sticky-head" v-sticky="{ oben: 0, übergeordnetes Element:'#appMainDom' }" > ... </el-Tabelle> veranschaulichen
Quellcode des Gitee-Falls: Hauptquellcode:/** * Ideen: * Der Abstand zwischen der Tabelle und der Oberseite* Stellen Sie den Abstand zwischen der Tabelle und der Oberseite so ein, dass sie die Oberseite aufnimmt --- offsetTop1 * Ermittelt die Scroll-Distanz der Bildlaufleiste. * Wenn die Bildlaufleiste über offsetTop1 scrollt, wird die Tabelle automatisch nach oben verschoben. */ Vue von „vue“ importieren const tableStickyObj = {} const __STICKY_TABLE = { // Stil für festen Header festlegen doFix (dom, top, data) { const { uid, domType, isExist } = Daten const uObj = tableStickyObj[uid] const curObj = uObj[domTyp] const headerRect = tableStickyObj[uid].headerRect wenn (!istExistiert) { dom.style.position = "fest" dom.style.zIndex = "2001" dom.style.top = oben + 'px' } uObj.tableWrapDom.style.marginTop = headerRect.height + 'px' wenn (domType === 'fest') { dom.style.left = aktuellesObj.left + 'px' } sonst wenn (domType === 'fixedRight') { dom.style.left = aktuellesObj.left + 1 + 'px' } }, // Formatierung des fixierten Headers aufheben removeFix (dom, data) { const { uid, domType } = Daten // dom.parentNode.style.paddingTop = 0 const uObj = tableStickyObj[uid] const curObj = uObj[domTyp] dom.style.position = "statisch" dom.style.top = "0" dom.style.zIndex = "0" uObj.tableWrapDom.style.marginTop = "0" wenn (domType === 'fest') { curObj.dom.style.top = "0" } sonst wenn (domType === 'fixedRight') { curObj.dom.style.top = "0" } }, // Klasse zum festen Header hinzufügen addClass (dom, fixtop, daten) { Fixtop = Fixtop || 0 const isExist = dom.classList.contains('festgelegt') data.isExist = !!isExist if (!isExist) { // Wenn es existiert, nicht hinzufügen dom.classList.add('fixed') } this.doFix(dom, fixtop, data) }, // Klasse aus festem Header entfernen removeClass (dom, Daten) { wenn (dom.classList.contains('fixiert')) { dom.classList.remove('behoben') this.removeFix(dom, Daten) } }, /** * Berechnen Sie die obere Distanz eines Elements relativ zum übergeordneten Element* @param {Nodes} e ein Element* @param {String} domId übergeordnetes Element-ID * @param {Boolean} isParent, ob es ein übergeordnetes Element ist * @returns {Number} */ getPosY(el, domId) { lass offset = 0 const pDom = el.offsetParent wenn (pDom != null und '#' + el.id !== domId) { Offset = el.OffsetTop Offset += this.getPosY(pDom, domId) } Rücklaufversatz }, // Die horizontale Koordinate des Elements abrufen (relativ zum Fenster) getPosX (e) { var offset = e.offsetLeft wenn (e.offsetParent != null) Offset += this.getPosX(e.offsetParent) Rücklaufversatz }, fixHead (scrollDom, el, uid, Bindung) { dies.fixHead1(dieses, { scrollDom, el, uid, Bindung }) }, // Die Hauptfunktion, um zu bestimmen, ob der Header fixHead1 repariert werden soll: sticky_throttle((_this, { scrollDom, el, uid, binding }) => { const top = Bindung.Wert.top /** * myTop ist die Höhe des aktuellen Elements aus dem übergeordneten Scroll-Container. * fixtop Die absolute Positionierungshöhe, die für das aktuelle Element festgelegt werden muss. * parentHeight Die Höhe des scrollenden übergeordneten Containers. */ // Tabellenkopfzeile DOM-Knoten const headerWrapDom = el.children[1] // el-table__header-wrapper const headerTop = tableStickyObj[uid].headerRect.top const scrollTop = scrollDom.scrollTop const fixedHeadDom = tableStickyObj[uid].fixed.headerDom const fixedHeadRightDom = tableStickyObj[uid].fixedRight.headerDom wenn (scrollTop >= headerTop) { const fixtop = top + scrollDom.getBoundingClientRect().top // Wenn die Kopfzeile zum Anfang des übergeordneten Containers scrollt. feste Positionierung_dies.addClass(headerWrapDom, fixtop, { domType: 'mainBody', uid }) fixedHeadDom && _this.addClass(fixedHeadDom, fixtop, { domType: 'fixed', uid }) fixedHeadRightDom && _this.addClass(fixedHeadRightDom, fixtop, { domType: 'fixedRight', uid }) } anders { // Wenn die Tabelle nach oben scrollt und in den übergeordneten Container scrollt. Feste Positionierung abbrechen_this.removeClass(headerWrapDom, { domType: 'mainBody', uid }) fixedHeadDom && _this.removeClass(fixedHeadDom, { domType: 'fixed', uid }) fixedHeadRightDom && _this.removeClass(fixedHeadRightDom, { domType: 'fixedRight', uid }) } }, 100, { eventType: 'fixHead111' }), // setzeKopfbreite(Daten) { this.setHeadWidth1(diese, Daten) }, // Wenn der Header auf Fix gesetzt wird, wird die Breite des Header-Containers auf die Breite des Tabellenkörpers gesetzt setHeadWidth1: sticky_debounce((_this, data) => { const { el, uid, Bindung, Ereignistyp } = Daten const { scrollDom } = tableStickyObj[uid] const headerWrapDom = el.children[1] // el-table__header-wrapper const headerH = headerWrapDom.offsetHeight const distTop = _this.getPosY(headerWrapDom, binding.value.parent) const scrollDistTop = _this.getPosY(scrollDom) // Der Abstand zwischen der Bildlaufleiste und der oberen TabelleStickyObj[uid].headerRect.top = distTop + headerH - scrollDistTop / 3 // Der Abstand zwischen der Kopfzeile und der oberen Kante - die Höhe der Kopfzeile selbst - der Abstand zwischen der Bildlaufleiste und der oberen TabelleStickyObj[uid].headerRect.height = headerH // TabelleStickyObj[uid].headerRect.width = TabelleW // Debugger // linke/rechte Kopfzeile korrigiert // Stellen Sie sicher, dass jede Aktualisierung nur einmal erfolgt // tableStickyObj[uid].fixed.dom = '' _this.initFixedWrap({ el, uid, Ereignistyp, Schlüssel: 'fixed', Klassenname: 'el-table__fixed', Klassenname1: 'el-table__fixed-header-wrapper' }) _this.initFixedWrap({ el, uid, Ereignistyp, Schlüssel: 'fixedRight', Klassenname: 'el-table__fixed-right', Klassenname1: 'el-table__fixed-header-wrapper' }) // Debugger // Breite des aktuellen Tabellenkörpers abrufen const bodyWrapperDom = el.getElementsByClassName('el-table__body-wrapper')[0] const width = getComputedStyle(bodyWrapperDom).width // Legen Sie die Breite der Tabelle fest. Dabei ist standardmäßig die Breite mehrerer Tabellen auf einer Seite gleich. Sie können also direkt durchlaufen und Werte zuweisen oder const tableParent = el.getElementsByClassName('el-table__header-wrapper') entsprechend Ihren Anforderungen separat festlegen. für (lass i = 0; i < tableParent.length; i++) { tableParent[i].style.width = Breite } // Debugger _this.fixHead(scrollDom, el, uid, binding) // Ein Prozess, um zu bestimmen, ob die Oberseite fixiert ist}), initFixedWrap (Daten) { const { Schlüssel, el, Ereignistyp, Klassenname, Klassenname1, uid } = Daten // Stellen Sie sicher, dass jede Aktualisierung nur einmal erfolgt, wenn (eventType === 'resize' || !tableStickyObj[uid][key].dom) { const tableFixedDom = el.getElementsByClassName(Klassenname) wenn (tableFixedDom.length) { const fixedDom = tableFixedDom[0] const arr = fixedDom.getElementsByClassName(className1) // const headW = getComputedStyle(fixedDom).width tableStickyObj[uid][Schlüssel].dom = fixedDom wenn (arr.Länge) { const distLeft = this.getPosX(fixedDom) // Abstand von der linken Seite des Fensters const headDom = arr[0] headDom.style.width = KopfW tableStickyObj[uid][key].left = distLeft // Pixel von der linken Seite des Fensters if (key === 'fixedRight') { // Die Besonderheit der rechtsfixierten Ausrichtung headDom.classList.add('scroll-bar-h0') headDom.style.overflow = "auto" headDom.scrollLeft = headDom.scrollWidth headDom.style.overflow = 'hidden' // Auf Scrollen bis zum Ende einstellen, auf nicht scrollbar einstellen} else { headDom.style.overflow = "versteckt" } tableStickyObj[uid][key].headerDom = headDom // Nimm das erste} } } }, //Bestimmte Variablen des übergeordneten Elements überwachen (das übergeordnete Element muss über diese verfügen, um überwacht zu werden) beobachtet ({ el, binding, vnode, uid }) { // Überwachen, ob die linke Navigationsleiste gefaltet ist vnode.context.$watch('isNavFold', (val) => { vnode.context.$nextTick(() => { setzeTimeout(() => { // Debugger this.setHeadWidth({ el, uid, binding, eventType: 'Größe ändern' }) }, 200) }) }) } } /** * Drosselungsfunktion: Die Aufgabe wird innerhalb des angegebenen Zeitintervalls nur einmal ausgeführt* @param {function} fn * @param {Number} Intervall */ Funktion sticky_throttle (fn, Intervall = 300) { let canRun = true Rückgabefunktion () { wenn (!canRun) return canRun = false setzeTimeout(() => { fn.apply(diese, Argumente) canRun = wahr }, Intervall) } } /** * Anti-Shake: Die Aufgabe wird nur einmal innerhalb des angegebenen Zeitintervalls ausgeführt und die Zeit wird neu berechnet, wenn sie innerhalb dieses Zeitraums erneut ausgelöst wird. (Version der Anti-Shake-Funktion, die nicht sofort ausgeführt wird) * Wenn bestimmte Ereignisse häufig ausgelöst werden und dadurch viele Berechnungen oder sehr ressourcenintensive Vorgänge erforderlich sind, kann die Ausführung von Anti-Shake nur einmal innerhalb eines zusammenhängenden Zeitraums erzwungen werden * */ Funktion sticky_debounce (fn, Verzögerung, Konfiguration) { const _delay = Verzögerung || 200 Konfiguration = Konfiguration || {} // const _this = this // Dies zeigt auf common.js Rückgabefunktion () { const th = this // Das this zeigt auf die Instanz const args = arguments // EntprellungNum++ // let str = `, label: ${th && th.listItem && th.listItem.label}` wenn (fn.timer) { Zeitüberschreitung löschen(fn.timer) fn.timer = null } anders { // fn.debounceNum = debounceNum } fn.timer = setzeTimeout(Funktion () { // str = `, Bezeichnung: ${th && th.listItem && th.listItem.label}` fn.timer = null fn.apply(th, args) }, _Verzögerung) } } // Benutzerdefinierte Ereignisse global registrieren Vue.directive('sticky', { // Wenn das gebundene Element in das DOM eingefügt wird ... eingefügt (el, Bindung, vnode) { // Holen Sie sich die ID der aktuellen vueComponent. Als Schlüssel zum Speichern verschiedener Überwachungsereignisse const uid = vnode.componentInstance._uid // Den aktuellen Scroll-Container abrufen. Wenn das Dokument gescrollt wird. Der übergeordnete Parameter kann standardmäßig weggelassen werden const scrollDom = document.querySelector(binding.value.parent) || document.body // TODO: Betrachten Sie den Fall, in dem es kein binding.value.parent gibt. Wenn Sie sich erneut anmelden und direkt zur internen Seite gehen, if (!tableStickyObj[uid]) { tableStickyObj[uid] = { Flüssigkeit, fixFunObj: {}, // Wird verwendet, um den Scroll-Ereignis-Listener des Scroll-Containers zu speichern setWidthFunObj: {}, // Wird verwendet, um das Ereignis der Neuberechnung der Kopfbreite nach der Größenänderung der Seite zu speichern autoMoveFunObj: {}, // Benutzerspeicher Wenn es sich um ein lokales Scrollen innerhalb des DOM-Elements handelt und das Dokument scrollt, muss die Kopfzeile des Fix-Layouts auch mit dem Dokument nach oben scrollen scrollDomRect: {}, headerRect: { oben: 0, links: 0 }, fixed: {}, // links von der Tabelle schweben fixedRight: {}, // rechts von der Tabelle schweben // Bindung, // el, tableWrapDom: el.getElementsByClassName('el-table__body-wrapper')[0], scrollDom } } __STICKY_TABLE.watched({ el, binding, vnode, uid }) // Auf einige Variablen des übergeordneten Elements achten // Wenn die Fenstergröße geändert wird, die Breite der Tabellenüberschrift neu berechnen und festlegen und die Abhörfunktion im Abhörfunktionsobjekt speichern, um das Entfernen des Abhörereignisses zu erleichtern window.addEventListener('resize', (tableStickyObj[uid].setWidthFunObj = () => { __STICKY_TABLE.setHeadWidth({ el, uid, binding, eventType: 'resize' }) // Zuerst die Breite der Kopfzeile festlegen}) ) // Scroll-Listener-Ereignisse zum Scroll-Container hinzufügen. Und speichern Sie die Abhörfunktion im Abhörfunktionsobjekt, um das Entfernen des Abhörereignisses zu erleichtern scrollDom.addEventListener('scroll', (tableStickyObj[uid].fixFunObj = (e) => { __STICKY_TABLE.fixHead(scrollDom, el, uid, Bindung) })) }, // Nachdem die Komponente aktualisiert wurde. Berechnen Sie die Header-Breite neu componentUpdated (el, binding, vnode) { const uid = vnode.componentInstance._uid __STICKY_TABLE.setHeadWidth({ el, uid, binding, eventType: 'componentUpdated' }) }, // Alle Abhörereignisse entfernen, wenn der Knoten nicht gebunden ist. unbind (el, Bindung, vnode) { const uid = vnode.componentInstance._uid window.removeEventListener('Größe ändern', tableStickyObj[uid].setWidthFunObj) const scrollDom = document.querySelector(binding.value.parent) || Dokument scrollDom.removeEventListener('scroll', tableStickyObj[uid].fixFunObj) wenn (Bindung.Wert.übergeordnet) { document.removeEventListener('scrollen', tableStickyObj[uid].autoMoveFunObj) } } }) Dies ist das Ende dieses Artikels über die Verwendung von el-table in vue, um einen automatischen Deckeneffekt zu erzielen (unterstützt behoben). Weitere Informationen zur automatischen Decke von el-table finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Sortierung und Paginierung von MySQL-Abfragen
>>: Analyse der Docker-Methode zum Erstellen lokaler Images
Das Backend verwendet das Framework thinkphp3.2.3...
Vorwort Angesichts der verrückten Spekulationen u...
Inhaltsverzeichnis Lazy Loading CSS-Stile: HTML-T...
Inhaltsverzeichnis Vorbemerkungen Reproduktion de...
Der mathematische Ausdruck calc() ist eine Funkti...
1. Verwenden Sie den Curl-Befehl für den Standard...
Jeder muss die Zusammensetzung des Boxmodells von...
In diesem Artikel wird der spezifische Code zur V...
Verwenden Sie die For-Schleife, um das Zabbix-Ima...
Inhaltsverzeichnis Algorithmische Strategie Einze...
<br />Im vorherigen Artikel habe ich die Sch...
In diesem Artikel wird der Datenanzeigecode für d...
SpringBoot ist wie eine riesige Python, die sich ...
Inhaltsverzeichnis 1.v-Modell 2. Bindungseigensch...
Inhaltsverzeichnis 1. Vorteile der Verwendung von...