heinetz: IntersectionObserver

Hallo Forum,

mir fehlt es gerade an einer Idee, wie ich folgendes Problem lösen kann. Ich stelle in einem Container mit overflow:hidden eine Tabelle dar. Die Tabelle ist abhängig von der Viewportbreite breiter als der Container und ich möchte die nicht sichtbaren Zellen ausblenden. Das mache ich im Moment mit dem IntersectionObserver auf den Tabellenzellen, der beim Laden und beim Vergrössern/Verkleinern des Viewports feststellt, ob die jeweilige Tabellenzelle im Viewport ist. Aktuell mache ich die Zellen, die nicht vollständig im Viewport sind nur transparent (opacity:0). So werden keine abgeschnittenen Strings aber Weissraum dargestellt. Um auch diesen Weissraum loszuwerden, müsste ich aus opacity:0 ein display:none machen. Das funktioniert aber leider nur beim Verkleinern des Viewports. Denn eine einmal ausgeblendete Zelle kann ja dem IntersectionObserver schlecht das Signal geben, dass sie nun wieder vollständig im Viewport ist.

Hier fehlt es mir an einer Idee. Hat jemand eine ?

gruss, heinetz

  1. Hallo heinetz,

    width:0 ?

    Die Herausforderung bleibt natürlich, den Punkt zu erkennen ab dem die Spalte eingeblendet werden kann.

    Vielleicht solltest du den Anwendungsfall besser beschreiben, damit man sich eine Lösung überlegen kann.

    Rolf

    --
    sumpsi - posui - obstruxi
  2. Idee (ungetestet)

    • via MutationObserver die Breite des Containers überwachen.
    • via JS ein <style>-Element mit td:nth-of-type()-Selektor schreiben / updaten

    Voraussetzung

    • keine Verwendung des colspan-Attributes vorhanden

    Ablauf

    Wenn der MutationObserver anschlägt:

    1. <style>Tag-Inhalt neutralisieren (wenn vorhanden). Z.B. den Selector anpassen td:nth-of-type(n)
    2. Anzahl anzeigbarer Zellen ermitteln
    3. <style>Tag-Inhalt neu schreiben, dabei:nth-of-type()-Selector auf Zellen-Anzahl anpassen. Z.B. td:nth-of-type(n+12)
    1. Hallo,

      • via MutationObserver die Breite des Containers überwachen.

      in den seltensten Fällen ändert sich die Größe eines Elements bei konstanter Viewportgröße, daher reicht meistens das resize-Event. Und wenn nicht, gibt es für diesen Fall den ResizeObserver.

      Gruß
      Jürgen

    2. Korrektur

      MutationObserver ist in diesem Fall falsch, denn der reagiert nur auf Änderungen im DOM.

      Wie @JürgenB schreibt ist der ResizeObserver* (oder einfach das resize-Event, wenn es passt) der richtige Trigger. Der Rest meiner Idee bleibt gleich.

      * https://caniuse.com/?search=ResizeObserver


      (Kann das bitte ein Admin in meinem obigen Beitrag vermerken. Danke.)

  3. Hallo,

    bei meiner Navigation prüfe ich, ob sie noch in eine Zeile passt, wenn nicht wird sie durch einen Menü-Button ersetzt. Dazu lausche ich auf das resize-Event, gebe im Handler der Zeile die volle Breite und prüfe, ob sie noch passt. Das geht im JS so schnell, dass man das nicht sieht.

    Gruß
    Jürgen

    1. @@JürgenB

      Das geht im JS so schnell, dass man das nicht sieht.

      Das heißt, das JS dafür befindet sich in der HTML-Ressource?

      😷 LLAP

      --
      „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
      1. Hallo Gunnar,

        Das geht im JS so schnell, dass man das nicht sieht.

        Das heißt, das JS dafür befindet sich in der HTML-Ressource?

        jein, bei meiner Navigation in einer JS-Datei. Aber im Wiki-Tutorial ist alles (HTML, CSS und JS) in einer Datei. Bei diesem Problem habe ich aber keinen Unterschied bemerkt. Daher verstehe ich den tieferen Sinn deiner Frage auch nicht. Oder geht das in die Richtung: „Was passiert ohne bzw. mit verzögert geladenem Javascript?“

        Gruß
        Jürgen

        1. @@JürgenB

          Oder geht das in die Richtung: „Was passiert ohne bzw. mit verzögert geladenem Javascript?“

          Genau das.

          😷 LLAP

          --
          „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
          1. Hallo Gunnar,

            OK. Ohne JS wird das Menü als Button angezeigt. Mit JS wird geprüft, ob der Platz reicht, und wenn ja, wird auf die breite Version umgestellt.

            Bisher hatte ich es noch nie, daß von den drei Dateien für HTML, CSS und Javascript eine oder zwei verzögert geladen wurden. Daher weiß ich auch nicht, wie das dann aussieht.

            Gruß
            Jürgen

            1. @@JürgenB

              OK. Ohne JS wird das Menü als Button angezeigt.

              ?? Und wie wird das ohne JS geöffnet?

              details-Element? Hab letztens mal nachgrfragt. Léonie Watson meinte, das sei in puncto Barrierefreiheit auch OK.

              Bisher hatte ich es noch nie, daß von den drei Dateien für HTML, CSS und Javascript eine oder zwei verzögert geladen wurden.

              Du warst noch nie im Lie-Fi?

              😷 LLAP

              --
              „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
              1. Hallo Gunnar,

                OK. Ohne JS wird das Menü als Button angezeigt.

                ?? Und wie wird das ohne JS geöffnet?

                durch Mausklick, Tastenklick oder Touch. Javascript wird für den Komfort und für den Polyfill benötigt.

                details-Element? Hab letztens mal nachgrfragt. Léonie Watson meinte, das sei in puncto Barrierefreiheit auch OK.

                Das höre ich gerne.

                Bisher hatte ich es noch nie, daß von den drei Dateien für HTML, CSS und Javascript eine oder zwei verzögert geladen wurden.

                Du warst noch nie im Lie-Fi?

                Ständig. Bei uns würde ich mich über Funklöcher freuen, wir haben Funkinseln. 😀

                Bei einigen Seiten, auch beim Forum, habe ich es schon mal gehabt, dass die Seite ohne css kam. Aber bei meiner Site kommt alles vom gleichen Server, da gab es bisher nur alles oder nichts.

                Gruß
                Jürgen

                1. @@JürgenB

                  Bei uns würde ich mich über Funklöcher freuen, wir haben Funkinseln. 😀

                  Figur-Grund-Wahrnehmung 😀

                  😷 LLAP

                  --
                  „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
  4. Umsetzung meiner obigen Idee, aber richtigerweise mit dem resize-Event.

    <div> <!-- container -->
      <table id="foo">
        <tr>
          <td>lorem</td>
          <!-- ... -->
        </tr>
      </table>
    </div>
    

    Der Container kann padding und border haben, denn das Script berücksichtigt diese.

    div {
      border: 2px solid;
      padding: 1rem;
    }
    
    table {
      width: 100%;
    }
    

    Anmerkung: Nur im Firefox 81.0 ((64-Bit) auf Windows) getestet.

    const tableID = "foo";
    const table = document.getElementById(tableID);
    const container = table.parentElement;
    const tableCells = table.querySelectorAll("tr:first-of-type > td");
    //
    const styleElement = document.createElement("style");
    container.insertBefore(styleElement, table);
    //
    function css() {
      let i = 1;
      let containerContentWidth = parseInt(
        window.getComputedStyle(container).width,
        10
      );
    
      for (let cell of tableCells) {
        let offsetRight = cell.offsetLeft + cell.offsetWidth;
    
        if (offsetRight <= containerContentWidth) {
          i++;
        } else {
          break;
        }
      }
    
      return "#" + tableID + " td:nth-of-type(n+" + i + "){display:none;}";
    }
    
    //
    styleElement.innerText = css();
    window.onresize = function () {
      styleElement.innerText = "";
      styleElement.innerText = css();
    };
    
  5. @@heinetz

    Die Tabelle ist abhängig von der Viewportbreite breiter als der Container und ich möchte die nicht sichtbaren Zellen ausblenden.

    Wenn die Information in diesen Tabellenzellen völlig unwichtig ist, warum werden die dann auf großen Viewports angezeigt?

    😷 LLAP

    --
    „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
    1. Hallo Gunnar,

      habe ich auch überlegt, aber ich nehme an, es gibt einen Paginiermechanismus, der nicht auf Scrollbars basiert.

      Das ist dann die andere Frage: Ist es sinnvoll, die Daten mit einen Paginiermechanismus zu durchlaufen, oder kann man sie einfach allesamt in epischer Breite und Höhe darstellen und dem Anwender die Kontroller per Scrollbar in die Hand drücken.

      Ohne Kenntnis des Anwendungsfalls kann man das nicht beurteilen, d.h. wir müssen davon ausgehen, dass Heinetz die UX sinnvoll festgelegt hat.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. @@Rolf B

        Das ist dann die andere Frage: Ist es sinnvoll, die Daten mit einen Paginiermechanismus zu durchlaufen, oder kann man sie einfach allesamt in epischer Breite und Höhe darstellen und dem Anwender die Kontroller per Scrollbar in die Hand drücken.

        Letzteres würde ich bejahen. Warum ein Feature, das funktioniert und Nutzern bestens bekannt ist, nachbauen – und das mit zweifelhaftem Erfolg (Erwartungskonformität, Barrierefreiheit)?

        Ohne Kenntnis des Anwendungsfalls kann man das nicht beurteilen, d.h. wir müssen davon ausgehen, dass Heinetz die UX sinnvoll festgelegt hat.

        Die Erfahrung lehrt, dass man eher vom Gegenteil ausgehen sollte.

        😷 LLAP

        --
        „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
        1. Hallo Gunnar,

          Die Erfahrung lehrt, dass man eher vom Gegenteil ausgehen sollte.

          Ja, sicher. AB Probleme sind hier täglich Brot.

          Letzteres würde ich bejahen

          Kannst Du ohne Kenntnis des Usecase nicht. Es könnten 1000 potenzielle Spalten sein und man muss filtern, um eine sinnvolle Anzeige zu bekommen.

          Oder Heinetz möchte ein paar Spalten fixieren und den Rest blättern (was man mit einer Table nicht gut hinbekommt). Sowas hatte ich neulich im Büro; ich hab's mit 2 Tabellen nebeneinander gemacht und mir den Wolf gebastelt, bis die Zeilen auch beim Zoomen gleich hoch blieben. Zu 100% stimmt es immer noch nicht (die fixierten Spalten sind teils leer und das bringt die Höhe durcheinander, keine Ahnung wieso). Da kann man es für einfacher halten, per Paginierung einfach die Spalteninhalte auszutauschen.

          Rolf

          --
          sumpsi - posui - obstruxi