Fermer

juin 1, 2020

En-tête de tableau collant lors du défilement de la page


Souvent, vous pouvez vous retrouver à construire une table pour afficher un grand nombre de données. Dans des cas comme celui-ci, vous souhaiterez peut-être que les en-têtes de ce tableau «collent» en haut du tableau afin que vous puissiez toujours voir l'en-tête de colonne comme votre défilement dans le tableau. Une situation simple consiste à ajouter «table-layout: fixed» à la balise tbody et thead. C'est très bien si vous voulez une vue de table fixe qui ne s'affiche pas au-delà des limites de page.

 Vue de table fixe

Comme vous pouvez le voir ci-dessus. Ce type de table d'en-tête «collant» a une hauteur fixe et un corps déroulant. Cependant, dans certains cas, un client peut souhaiter un corps de table qui n'a pas de hauteur fixe. Par exemple, le client peut souhaiter une page de recherche avec un tableau de résultats s'étendant au-delà des limites de l'écran. Malheureusement, il n'y a pas de solution facile pour permettre à un en-tête de coller en haut de la page lorsque vous faites défiler. Heureusement, je suis sur le point de vous montrer comment le faire grâce à ma propre solution personnalisée!

Bien que cette solution personnalisée puisse être adaptée à n'importe quel framework frontal, il convient de noter que j'utilise Angular 6 avec dactylographié.

Code

Le but ici est de tromper l'utilisateur final en lui faisant croire que l'en-tête colle réellement au haut de la page. En réalité, nous utilisons deux en-têtes pour la même table: une qui est l'en-tête de table normale qui se déplace avec la table lors du défilement, et une seconde qui colle en haut de la page et apparaît lorsque le premier en-tête est hors de vue. vous pouvez le voir ci-dessous:

HTML

Id Nom Description
Id Nom Description
{{data.id}} {{data .name}} {{data.description}}

CSS

 e {
    couleur de fond: bleu clair;
}

table {
    border-collapse: effondrement;
    largeur: 100%;
    affichage: table;
}

.hide-sticky {
    affichage: aucun;
}

.sticky {
    position: fixe;
    en haut: 0;
    indice z: 1;
}
 Covid 19

Comme vous pouvez le voir dans le code ci-dessus, il y a en fait deux en-têtes dans le code. Un en-tête qui n'a pas de classe (l'en-tête de table normal) et un qui a les classes «sticky hide-sticky» (l'en-tête collant caché). Dans le CSS, il est clair que l'en-tête collant est masqué et fixé en haut de l'écran. Génial! Il est maintenant temps pour la partie difficile: la logique.

Typescript

 import {
  Composant,
  OnInit,
  HostListener,
} de '@ angular / core';
importer {SimpleDataObject} depuis './models/simple-data-object.model';

@Composant({
  sélecteur: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
la classe d'exportation AppComponent implémente OnInit {
  title = 'sticky-header-app';

  dataSource: SimpleDataObject [];

  // Ceci est l'ajustement de style lors de la définition des mesausrments des en-têtes de colonne collants
  headerStylingAdjustment = 3;

  ngOnInit () {
    this.initializeData ();
  }

  initializeData () {
    this.dataSource = [];

    pour (soit i = 0; i <100; i ++) {
      this.dataSource.push ({
        id: i,
        nom: 'Simple Data Name' + i,
        description: «Test de description»,
      } comme SimpleDataObject);
    }
  }

  @HostListener ('window: scroll', ['$event'])
  onWindowScroll () {
    this.handleScroll ();
  }

  handleScroll privé () {
    const table = document.getElementById ('table');
    const stickyTableHead = document.getElementById ('sticky-table-head');
    const tableBody = document.getElementById ('table-body');
    const originalHeaders = document.getElementsByClassName (
      «en-tête sur mesure»
    );
    const stickyHeaders: NodeListOf  = document.querySelectorAll (
      'th.header-to-set'
    );

    if (table.getBoundingClientRect (). top  0) {
      stickyTableHead.classList.remove ('hide-sticky');

      pour (soit i = 0; i  0 &&
      stickyTableHead.classList.contains ('sticky')
    ) {
      stickyTableHead.classList.add ('hide-sticky');
    }
  }
} 

D'accord – je l'admets, il se passe beaucoup de choses ici, alors décomposons-le… La première chose à faire est d'ajouter l'écouteur pour faire défiler la page. Cela se voit sur la ligne 37-40:

 @HostListener ('window: scroll', ['$event'])
 onWindowScroll () {
   this.handleScroll ();
 } 

L'écouteur exécute ma fonction de gestionnaire personnalisé "handleScroll ()" lorsqu'il détecte que l'utilisateur a fait défiler la page.

 const table = document.getElementById ('table');
const stickyTableHead = document.getElementById ('sticky-table-head');
const tableBody = document.getElementById ('table-body');
const originalHeaders = document.getElementsByClassName (
  «en-tête sur mesure»
);
const stickyHeaders: NodeListOf  = document.querySelectorAll (
  'th.header-to-set'

Lorsque la fonction «handleScroll ()» est appelée, elle enregistre d'abord certains des éléments DOM sous forme de variables pour permettre une manipulation aisée des composants à l'écran.

Ensuite, l'objectif est de gérer quand l'en-tête normal disparaît de l'écran – c'est-à-dire lorsque l'en-tête doit rester en haut de l'écran.

 if (table.getBoundingClientRect (). top  0) {
      stickyTableHead.classList.remove ('hide-sticky');

      pour (soit i = 0; i <originalHeaders.length; i ++) {
        const originalHeader = originalHeaders [i] as HTMLElement;
        stickyHeaders [i] .style.columnWidth =
          originalHeader.clientWidth - this.headerStylingAdjustment + 'px';
      }
 } 

L'instruction "if" valide que l'en-tête doit rester en haut de l'écran à l'aide de la table.getBoundingClientRect (). Top <= 0. Si l'instruction renvoie true, la classe "hide-sticky" est supprimée de la classe en-tête collant. Malheureusement, lorsqu'il est «corrigé», l'en-tête perdra tout formatage du tableau – cela signifie que nous devons ajuster la taille des en-têtes de colonne pour correspondre au tableau. La boucle «pour» parcourra le tableau des en-têtes normaux et réinitialisera les longueurs de chaque en-tête dans la tête collante. Une chose importante à noter est que nous utilisons la largeur du client comme mesure, pas la largeur de décalage. La largeur du client inclura la marge de l'élément DOM, tandis que la largeur de décalage l'exclura dans la mesure. Cela n'a finalement pas d'importance, car les DEUX excluent tout remplissage de l'élément. Pour tenir compte des pixels de remplissage manquants, la constante «headerStylingAdjstment» est ajoutée à la nouvelle largeur de l'en-tête collant

La dernière chose à faire est de s'assurer que l'en-tête collant disparaît à nouveau lorsque l'en-tête normal est de retour dans la vue de page. . Ceci est géré par la deuxième instruction if aux lignes 63 à 68.

 if (
      tableBody.getBoundingClientRect (). top> 0 &&
      stickyTableHead.classList.contains ('sticky')
    ) {
      stickyTableHead.classList.add ('hide-sticky');
 } 

Cela ajoute simplement la classe "hide-sticky" à l'élément DOM d'en-tête collant une fois que l'en-tête normal est de retour sur la page.

Conclusion

Ce que je vous ai montré, c'est comment ajouter un en-tête collant à une table sans hauteur définie. Cela implique une petite manipulation, mais il suffit simplement d'ajouter un deuxième en-tête qui reste en haut de la page une fois que les en-têtes originaux ont défilé devant la vue.

À propos de l'auteur <! -: hsmith, Consultant technique associé ->

Hunter est consultant technique associé à l'unité commerciale Sitecore / Episerver chez Perficient. Son travail chez Perficient a été principalement en tant que développeur d'applications Web Dev Full-Stack. En tant que tel, il travaille avec des clients pour fournir des solutions techniques personnalisées en utilisant Angular, React, C #, SQL, etc.

Plus d'informations de cet auteur






Source link