el-table in vue realisiert automatischen Deckeneffekt (unterstützt feste)

el-table in vue realisiert automatischen Deckeneffekt (unterstützt feste)

Vorwort

Nach 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

  • Abstand von der Tabellenspitze
  • Stellen Sie den Abstand zwischen der Tabelle und der Oberseite so ein, dass sie die Oberseite aufnimmt – offsetTop1
  • Holen Sie sich die Scroll-Distanz der Bildlaufleiste
  • Wenn die Bildlaufleiste offsetTop1 scrollt, bewegt sich die Tabelle automatisch nach oben

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

Parametername Typ veranschaulichen
Spitze Nummer Wie viele Pixel beträgt die Bildlaufleiste von oben, automatisch an der Oberseite befestigt
Elternteil Zeichenfolge Das scrollende DOM-Element querySelector wird intern verwendet, um das Element abzurufen

Quellcode des Gitee-Falls:
https://gitee.com/kaiking_g/test-element-by-vue.git

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:
  • Benutzerdefinierte Vue-Anweisungen generieren UUID-Scroll-Überwachungscode, um den Tab-Tabellendeckeneffekt zu erzielen
  • Vue realisiert die Effekte von Decke, Ankerpunkt und Scroll-Highlight-Button
  • Implementieren einer Vue-Deckenankerkomponentenmethode
  • Mehrere Layoutmethoden für die Multiroute-Tabellenkopfzeilendecke in Vue
  • Beispielcode für die Vue-Entwicklung zum Erreichen eines Deckeneffekts
  • Vue realisiert die Anzeige eines Elements an der Decke oder an einer festen Position (überwacht Bildlaufereignisse).

<<:  Sortierung und Paginierung von MySQL-Abfragen

>>:  Analyse der Docker-Methode zum Erstellen lokaler Images

Artikel empfehlen

Verwendung des Linux-Befehls „userdel“

1. Befehlseinführung Der Befehl userdel (User Del...

Grundlagen und Beispiele zur TypeScript-Aufzählung

Inhaltsverzeichnis Vorwort Was sind Enumerationen...

Gemeinsame Eigenschaften des Framesets (Unterteilung von Frames und Fenstern)

Ein Frame ist ein Webseitenbildschirm, der in mehr...

So löschen Sie schwebenden Beispielcode in CSS

Überblick Das Rahmendiagramm dieses Artikels ist ...

Lassen Sie uns über das v-on-Parameterproblem in Vue sprechen

Verwendung von v-on:clock in Vue Ich lerne derzei...

HTML-Tbody-Verwendung

Strukturierte Tabelle (nur IExplore) 1) Gruppieren...

3 Möglichkeiten, die maximale Anzahl von Verbindungen in MySQL richtig zu ändern

Wir alle wissen, dass die standardmäßige MySQL-Da...

JavaScript realisiert den Warteschlangenstrukturprozess

Inhaltsverzeichnis 1. Warteschlangen verstehen 2....

VUE+Canvas implementiert das Spiel God of Wealth und erhält Barren

Willkommen zur vorherigen Canvas-Spielserie: 《VUE...

Einführung in die Überwachung des MySQL MHA-Betriebsstatus

Inhaltsverzeichnis 1. Projektbeschreibung 1.1 Hin...

Detaillierte Erklärung der Tomcat-Verzeichnisstruktur

Inhaltsverzeichnis Verzeichnisstruktur bin-Verzei...