Anwendung IntersectionObserver
Nico R.
- api
- javascript
Hallo zusammen,
ich komme nochmal auf diesen Thread zurück. Ich hab jetzt mal versucht, den IntersectionObserver zu implementieren. Hier nochmal das alte Beispiel mit der scroll-Überwachung: https://fsv-optik.de/tests/test_bg2.html. Wenn 100px nach unten gescrollt wurde, wird das background-image ausgeblendet.
Mit dem Observer krieg ichs nicht hin. Da ist ja der Ansatz ein anderer. Der überwacht ja, ob ein Element einen bestimmten Bereich kreuzt. In meinem Fall will ich eigentlich den body überwachen. Der befindet sich ja per se im Viewport. Folglich ist in meinem Beispiel isIntersecting auch immer true. Dachte ich... In meinem Fall immer false.
Ich müsste in meinem Fall eigentlich messen, wann der body beginnt den Viewport am oberen Bereich zu verlassen. Ist das prinzipiell überhaupt möglich? Das scheint mir doch sehr frickelig. Bin ich da nicht auf einem Holzweg?
Hier mein kläglicher Versuch: https://fsv-optik.de/tests/test_bg_observer.html
Schöne Grüße
Nico
Hi,
Mit dem Observer krieg ichs nicht hin. Da ist ja der Ansatz ein anderer. Der überwacht ja, ob ein Element einen bestimmten Bereich kreuzt. In meinem Fall will ich eigentlich den body überwachen. Der befindet sich ja per se im Viewport. Folglich ist in meinem Beispiel isIntersecting auch immer true. Dachte ich... In meinem Fall immer false.
Evtl. ein Kind des Body benutzen? Das scrollt ja mit …
cu,
Andreas a/k/a MudGuard
Hallo Nico R.,
Ein IntersectionObserver kann entweder prüfen, ob sich zwei Elemente überschneiden (oder auch nicht), oder er kann prüfen, ob ein Element im Viewport ist (oder auch nicht).
Den body zu überwachen bringt nichts, weil der eigentlich immer im Viewport ist. Deswegen braucht man, um das „weit genug nach unten gescrollt“ zu erkennen, so etwas wie ein „Sensor-Element“. Gunnar hatte dazu einen Link auf einen Link zu einem Beispiel gemacht. Hier.
Der naive Ansatz ist, am oberen Rand des Inhalts ein leeres div mit Höhe 0 zu platzieren und es als Sensor-Element zu verwenden. Man dem Observer ein root von null (d.h. den Viewport), einen rootMargin von 100px (damit man 100px Luft hat, bis der Viewport als "verlassen" gilt und als threshold wählt man 0.
Im "unverscrollten" Zustand ist das Sensor-div auf Höhe 0. Beginnt man, nach unten zu scrollen, wandert es in Richtung -100px, bis es irgendwann darüber hinaus ist. In dem Moment wechselt das intersectionRatio auf 0 und der Observer ruft den Callback auf.
Gunnars „Verbesserung“ war, das HTML nicht durch ein Sensorelement vollzumüllen, sondern ein Element zu nehmen, das eh schon da ist: head
. head
ist normalerweise auf display:none
gesetzt, was es auch vor einem Observer versteckt, aber das kann man ja ändern:
head { display: block; }
head > * { display: none; }
Damit ist head sichtbar und sein Inhalt versteckt und nun kann das head-Element als Sensor dienen.
Verbesserung in Anführungszeichen – man kann über das Zweckentfremden des head als Scroll-Sensor durchaus diskutieren. Was nicht heißt, dass ich das gleich zum Bockmist erkläre, aber ein Prinzip von sauberem Code ist: verwende Dinge ihrer Bestimmung gemäß. Aus meiner Sicht ist <head> nicht dazu bestimmt, irgendwo sichtbar zu sein, auch nicht mit Höhe 0.
Aber ein weiteres Prinzip ist: Vermeide Markup, das nicht für den Inhalt wichtig ist. Diese beiden Prinzipien stehen hier im Konflikt, und verschiedene Leute wählen verschiedene Lösungen für Zielkonflikte. Ich hätte wohl ein Sensor-div verwendet. Gunnar hat anders entschieden. Aber Gunnar ist halt auch ein Code-Golfer 😉.
Rolf
Hi,
Der naive Ansatz ist, am oberen Rand des Inhalts ein leeres div mit Höhe 0 zu platzieren und es als Sensor-Element zu verwenden.
Gunnars „Verbesserung“ war, das HTML nicht durch ein Sensorelement vollzumüllen, sondern ein Element zu nehmen, das eh schon da ist:
head
.
könnte man hier auch ein Pseudo-Element (a la body::before) verwenden?
cu,
Andreas a/k/a MudGuard
Also manchmal hat man doch wirklich n Brett vorm Kopf. Ich hab ja genügend Elemente oben, die ich überwachen kann, unter anderem die Navigation. Jetzt funktionierts, wie es soll. Ich hoffe einfach mal, dass die Browser dieser Welt sich jetzt auch freuen :-)
Hier das funktionierende Beispiel: https://fsv-optik.de/tests/test_bg_observer.html
Danke und Gruß
Nico
@@Rolf B
Aus meiner Sicht ist <head> nicht dazu bestimmt, irgendwo sichtbar zu sein
Warum nicht? Man könnte Metadaten, die im head
schon vorhanden sind, auf der Seite anzeigen, ohne sie im body
nochmal zu duplizieren.
head {
display: block;
> * { display: none }
}
meta[name="author"], meta[property^="date"] {
display: inline;
&::before { content: attr(content) }
&:has(+ &)::after { content: "," }
}
☞ Nur nicht den Kopf verlieren!
Was jetzt aber wenig mit der Frage zu tun hat, ob man den head
observieren sollte, wenn er schon mal da ist, oder ein div
ins Markup einbauen sollte, was – wenn man das Markup allein betrachtet – überhaupt keinen Sinn macht.
Die einen sagen so, die anderen so. Harry Roberts (csswizardry) fand meine Idee clever.
Kwakoni Yiquan
Hallo Gunnar,
ne interessante Lösung. Ich für meinen Teil würde aber im Zweifel auch eher ein "Messelement" einbauen.
Was ist denn eigentlich das?
<meta property="dateCreated" content="2024-07-18"/>
Ich konnte dazu nicht viel finden. Auf https://search.gov/indexing/metadata.html werden diese Varianten aufgeführt:
<meta property="article:published_time" content="YYYY-MM-DD" />
<meta name="dc.date" content="YYYY-MM-DD" />
<meta name="dc.date.created" content="YYYY-MM-DD" />`
<meta name="dcterms.created" content="YYYY-MM-DD" />
Die unterscheiden sich nun wieder von deiner Variante. Was ist denn da nun los, kann man sich irgendwas davon aussuchen?
Schöne Grüße
Nico
Hallo Nico,
was Du als name
ins Meta-Element schreibst, ist deine Sache. Die Frage ist dann nur, wer es versteht.
Es gibt etliche standardisierte Namen, die unser Wiki leider nicht systematisch zu listen scheint. Ich verweise daher auf die Standardnamen bei Mozilla.
Die dc.* Namen entstammen der Dublin Core-Initiative. Welche Reichweite diese Initiative hat, kann ich schlecht beurteilen. Es gibt dazu einen Wikipedia-Artikel, der sogar auf unser Wiki verlinkt. Leider auf eine gelöschte Seite, das hab ich mal fix geflugst.
<meta property...>
hingegen ist mir fremd und den Spezifikationen auch. Es gibt <meta itemprop...>
, um Microdata notieren zu können.
Rolf
@@Rolf B
<meta property...>
hingegen ist mir fremd
und den Spezifikationen auch.
Nein. RDFa Primer, RDFa Lite, RDFa Core
Es gibt
<meta itemprop...>
, um Microdata notieren zu können.
Microdata ist eine blöde Idee von Hixie. RDFa ist ein vernüftiger Standard.
Das hatten wir doch schon das ein oder andere Mal.
Kwakoni Yiquan
Hallo Gunnar,
Das hatten wir doch schon das ein oder andere Mal.
Mag sein. Aber weil ich sowas nicht benutze, vergesse ich es wieder. Und im Wiki war's nicht gut verlunken, das habe ich mal geändert.
Rolf
@@Nico R.
Was ist denn eigentlich das?
<meta property="dateCreated" content="2024-07-18"/>
Eine Angabe in RDFa im Schema.org-Vokabular (angegeben in <html lang="de" vocab="https://schema.org/">
).
Kwakoni Yiquan
Hallo Nico,
Ich müsste in meinem Fall eigentlich messen, wann der body beginnt den Viewport am oberen Bereich zu verlassen. Ist das prinzipiell überhaupt möglich? Das scheint mir doch sehr frickelig. Bin ich da nicht auf einem Holzweg?
warum überwachst du nicht die Überschrift?
Gruß
Jürgen