IntersectionObserver
heinetz
- javascript
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
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
Idee (ungetestet)
MutationObserver
die Breite des Containers überwachen.<style>
-Element mit td:nth-of-type()
-Selektor schreiben / updatenVoraussetzung
colspan
-Attributes vorhandenAblauf
Wenn der MutationObserver
anschlägt:
<style>
Tag-Inhalt neutralisieren (wenn vorhanden). Z.B. den Selector anpassen td:nth-of-type(n)
<style>
Tag-Inhalt neu schreiben, dabei:nth-of-type()
-Selector auf Zellen-Anzahl anpassen. Z.B. td:nth-of-type(n+12)
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
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.)
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
@@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
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
@@JürgenB
Oder geht das in die Richtung: „Was passiert ohne bzw. mit verzögert geladenem Javascript?“
Genau das.
😷 LLAP
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
@@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
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
Grundlage für Zitat #2548.
@@JürgenB
Bei uns würde ich mich über Funklöcher freuen, wir haben Funkinseln. 😀
😷 LLAP
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();
};
@@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
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
@@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
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