| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/API/Intersection_Observer_API | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Mrz 2019 browserbergreifend verfgbar.
* Einige Teile dieser Funktion werden mglicherweise unterschiedlich gut untersttzt.
Die Intersection Observer API bietet eine Mglichkeit, asynchron nderungen der berschneidung eines Zielelements mit einem bergeordneten Element oder mit dem Viewport eines obersten Dokuments zu beobachten.
Historisch gesehen war das Erkennen der Sichtbarkeit eines Elements oder der relativen Sichtbarkeit zweier Elemente zueinander eine schwierige Aufgabe, fr die Lsungen unzuverlssig waren und dazu neigten, den Browser und die vom Nutzer aufgerufenen Websites trge zu machen. Mit der Reife des Webs ist das Bedrfnis nach solchen Informationen gewachsen. Informationen ber berschneidungen werden aus vielen Grnden bentigt, wie zum Beispiel:
Das Implementieren der berschneidungserkennung in der Vergangenheit beinhaltete Event-Handler und Schleifen, die Methoden wie Element.getBoundingClientRect() aufriefen, um die bentigten Informationen fr jedes betroffene Element aufzubauen. Da all dieser Code im Hauptthread luft, kann sogar einer dieser Prozesse zu Leistungsproblemen fhren. Wenn eine Seite mit diesen Tests geladen ist, kann es regelrecht hsslich werden.
Betrachten Sie eine Webseite, die unendliches Scrollen verwendet. Sie benutzt eine von einem Anbieter bereitgestellte Bibliothek, um die periodisch auf der Seite platzierten Anzeigen zu verwalten, hat hier und da animierte Grafiken und nutzt eine benutzerdefinierte Bibliothek, die Benachrichtigungsboxen und dergleichen zeichnet. Jede dieser Routinen zur berschneidungserkennung luft im Hauptthread. Der Autor der Website knnte sich dessen nicht einmal bewusst sein, da er mglicherweise nur sehr wenig ber das Innenleben der beiden Bibliotheken wei, die er verwendet. Whrend der Nutzer die Seite scrollt, werden diese Routinen zur berschneidungserkennung stndig whrend des Scrollvorgangs ausgelst, was zu einer Erfahrung fhrt, die den Nutzer frustriert mit dem Browser, der Website und seinem Computer zurcklsst.
Die Intersection Observer API lsst den Code eine Callback-Funktion registrieren, die immer dann ausgefhrt wird, wenn ein bestimmtes Element ein- oder aus einer berschneidung mit einem anderen Element (oder dem Viewport) eintritt oder verlsst, oder wenn sich die berschneidung zwischen zwei Elementen um einen bestimmten Betrag ndert. Auf diese Weise mssen Websites nichts mehr im Hauptthread tun, um diese Art von Elementberschneidung zu beobachten, und der Browser ist frei, die Verwaltung von berschneidungen nach eigenem Ermessen zu optimieren.
Eine Sache, die die Intersection Observer API nicht kann: Logik basierend auf der genauen Anzahl der berlappenden Pixel auslsen oder spezifisch darauf, welche es sind. Sie lst nur den allgemeinen Anwendungsfall Wenn sie sich mit irgendwo um N% berschneiden, muss ich etwas tun aus.
Die Intersection Observer API ermglicht es Ihnen, einen Callback zu konfigurieren, der aufgerufen wird, wenn eine der folgenden Bedingungen eintritt:
Typischerweise mchten Sie nderungen der berschneidung in Bezug auf den nchsten scrollbaren Vorfahren des Zielelements beobachten, oder, wenn das Zielelement kein Nachkomme eines scrollbaren Elements ist, den Gerte-Viewport. Um die berschneidung relativ zum Gerte-Viewport zu beobachten, geben Sie null fr die root-Option an. Lesen Sie weiter fr eine detailliertere Erklrung zu den Optionen des Intersection Observer.
Ob Sie den Viewport oder ein anderes Element als Wurzel verwenden, die API funktioniert auf die gleiche Weise, indem sie eine von Ihnen bereitgestellte Callback-Funktion ausfhrt, wann immer sich die Sichtbarkeit des Zielelements so ndert, dass es gewnschte Mengen an berschneidung mit der Wurzel berschreitet.
Der Grad der berschneidung zwischen dem Zielelement und seiner Wurzel ist das berschneidungsverhltnis. Dies ist eine Darstellung des Prozentsatzes des Zielelements, der als Wert zwischen 0,0 und 1,0 sichtbar ist.
Erstellen Sie den Intersection Observer, indem Sie dessen Konstruktor aufrufen und eine Callback-Funktion bergeben, die jedes Mal ausgefhrt wird, wenn ein Schwellenwert in die eine oder andere Richtung berschritten wird:
const options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
scrollMargin: "0px",
threshold: 1.0,
};
const observer = new IntersectionObserver(callback, options);
Ein Schwellenwert von 1,0 bedeutet, dass, wenn 100 % des Ziels innerhalb des durch die root-Option angegebenen Elements sichtbar sind, der Callback aufgerufen wird.
Das an den Konstruktor IntersectionObserver() bergebene options-Objekt ermglicht es Ihnen, die Umstnde zu steuern, unter denen der Callback des Observers aufgerufen wird. Es hat die folgenden Felder:
rootDas Element, das als Viewport zur berprfung der Sichtbarkeit des Ziels verwendet wird. Muss der Vorfahre des Ziels sein. Standardmig wird der Browser-Viewport verwendet, wenn nicht angegeben oder wenn null.
rootMarginRand um die Wurzel. Ein String mit einem bis vier Werten, hnlich der CSS-margin-Eigenschaft, z. B. "10px 20px 30px 40px" (oben, rechts, unten, links). Die Werte knnen nur in Pixeln (px) oder Prozent (%) angegeben werden. Diese Wertemenge dient dazu, jede Seite des Begrenzungsrahmens der Wurzel zu vergrern oder zu verkleinern, bevor berschneidungen berechnet werden. Negative Werte verkleinern den Begrenzungsrahmen des Wurzelelements und positive Werte vergrern ihn. Der Standardwert, wenn nicht angegeben, ist "0px 0px 0px 0px".
scrollMarginRand um geschachtelte Scrollcontainer, der dieselben Werte annimmt und denselben Standard hat wie rootMargin.
Die Rnder werden auf geschachtelte scrollbare Container angewendet, bevor berschneidungen berechnet werden.
Positive Werte vergrern das Clipping-Rechteck des Containers, sodass Ziele frher berschneiden knnen, whrend negative Werte das Clipping-Rechteck verkleinern.
thresholdEntweder eine einzelne Zahl oder ein Array von Zahlen, die angeben, bei welchem Prozentsatz der Sichtbarkeit des Ziels der Callback des Observers ausgefhrt werden soll. Wenn Sie nur erkennen mchten, wenn die Sichtbarkeit die 50 %-Marke berschreitet, knnen Sie einen Wert von 0,5 verwenden. Wenn der Callback jedes Mal ausgefhrt werden soll, wenn die Sichtbarkeit um weitere 25 % variiert, wrden Sie das Array [0, 0.25, 0.5, 0.75, 1] angeben. Der Standard ist 0 (was bedeutet, dass der Callback ausgefhrt wird, sobald das Zielelement die Grenze der Wurzel schneidet oder berhrt, auch wenn noch keine Pixel sichtbar sind). Ein Wert von 1,0 bedeutet, dass der Schwellenwert nicht als berschritten betrachtet wird, bis jedes Pixel sichtbar ist.
delay Wenn die Sichtbarkeit des Ziels verfolgt wird (trackVisibility ist true), kann diese Option verwendet werden, um die minimale Verzgerung in Millisekunden zwischen Benachrichtigungen von diesem Observer festzulegen.
Das Begrenzen der Benachrichtigungsrate ist wnschenswert, da die Sichtbarkeitsberechnung rechnerisch intensiv ist.
Wenn Sie die Sichtbarkeit verfolgen, wird der Wert auf 100 gesetzt fr jeden Wert unter 100 und Sie sollten den grten tolerierbaren Wert verwenden.
Der Wert ist standardmig 0.
trackVisibility Ein boolescher Wert, der angibt, ob dieser IntersectionObserver nderungen in der Sichtbarkeit eines Ziels verfolgt.
Wenn false, meldet der Browser berschneidungen, wenn das Zielelement in den Viewport des Wurzelelements scrollt.
Wenn true, berprft der Browser zustzlich, ob das Ziel tatschlich sichtbar ist und nicht von anderen Elementen verdeckt oder mglicherweise durch einen Filter, reduzierte Deckkraft oder eine Transformation verzerrt oder verborgen wurde.
Der Standardwert ist false, da das Verfolgen der Sichtbarkeit rechnerisch intensiv ist.
Wenn dies gesetzt ist, sollte auch eine delay eingestellt werden.
Der an den Konstruktor IntersectionObserver() bergebene Callback erhlt eine Liste von IntersectionObserverEntry-Objekten und den Observer:
const callback = (entries, observer) => {
entries.forEach((entry) => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
Die Liste der vom Callback empfangenen Eintrge enthlt ein IntersectionObserverEntry-Objekt fr jedes Schwellenwert-berschreitungsereignis es knnen mehrere Eintrge gleichzeitig empfangen werden, entweder von mehreren Zielen oder von einem einzelnen Ziel, das in kurzer Zeit mehrere Schwellenwerte berschreitet. Die Eintrge werden in einer Warteschlange versendet, daher sollten sie in der Reihenfolge des Generierens geordnet sein, aber Sie sollten vorzugsweise IntersectionObserverEntry.time verwenden, um sie korrekt zu ordnen. Jeder Eintrag beschreibt, wie viel von einem bestimmten Element mit dem Wurzelelement berschneidet, ob das Element als sich berschneidend betrachtet wird oder nicht usw. Der Eintrag enthlt nur Informationen ber diesen bestimmten Moment wenn Sie Informationen bentigen, die eine Verfolgung ber die Zeit erfordern, wie die Scrollrichtung und -geschwindigkeit, mssen Sie das mglicherweise selbst berechnen, indem Sie zuvor empfangene Eintrge speichern.
Beachten Sie, dass Ihr Callback im Hauptthread ausgefhrt wird. Es sollte so schnell wie mglich arbeiten; wenn etwas zeitaufwndiges getan werden muss, verwenden Sie Window.requestIdleCallback().
Der folgende Codeausschnitt zeigt einen Callback, der zhlt, wie oft Elemente vom Nichtberschneiden der Wurzel zum berschneiden mit mindestens 75 % bergehen. Bei einem Schwellenwert von 0,0 (Standard) wird der Callback ungefhr beim bergang des booleschen Werts von isIntersecting aufgerufen. Der Ausschnitt prft also zuerst, ob der bergang ein positiver ist, und bestimmt dann, ob intersectionRatio ber 75 % liegt, in diesem Fall erhht er den Zhler.
const intersectionCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let elem = entry.target;
if (entry.intersectionRatio >= 0.75) {
intersectionCounter++;
}
}
});
};
Sobald Sie den Observer erstellt haben, mssen Sie ihm ein Zielelement zum Beobachten angeben:
const target = document.querySelector("#listItem");
observer.observe(target);
// the callback we set up for the observer will be executed now for the first time
// it waits until we assign a target to our observer (even if the target is currently not visible)
Immer wenn das Ziel einen fr den IntersectionObserver angegebenen Schwellenwert erreicht, wird der Callback ausgefhrt.
Beachten Sie auch, dass das Ziel ein Nachkomme des Wurzelelements sein muss, wenn Sie die Option root angegeben haben.
Alle von der Intersection Observer API betrachteten Bereiche sind Rechtecke; Elemente, die unregelmig geformt sind, werden als das kleinste Rechteck betrachtet, das alle Teile des Elements umfasst. hnlich verhlt es sich, wenn der sichtbare Teil eines Elements nicht rechteckig ist, das berschneidungsrechteck des Elements wird als das kleinste Rechteck betrachtet, das alle sichtbaren Teile des Elements enthlt.
Es ist ntzlich, ein wenig darber zu verstehen, wie die verschiedenen von IntersectionObserverEntry bereitgestellten Eigenschaften eine berschneidung beschreiben.
Bevor wir die berschneidung eines Elements mit einem Container verfolgen knnen, mssen wir wissen, was dieser Container ist. Dieser Container ist die berlappungswurzel oder das Wurzelelement. Dies kann entweder ein bestimmtes Element im Dokument sein, das ein Vorfahre des zu beobachtenden Elements ist, oder null, um den Dokumentenviewport als den Container zu verwenden.
Das Wurzel-berlappungsrechteck ist das Rechteck, das zur berprfung gegenber dem Ziel oder den Zielen verwendet wird. Dieses Rechteck wird wie folgt bestimmt:
getBoundingClientRect() darauf zurckgegeben).Das Wurzel-berlappungsrechteck kann weiter durch Festlegen des Wurzelabstands, rootMargin, beim Erstellen des IntersectionObserver angepasst werden. Die Werte in rootMargin definieren Offsets, die zu jeder Seite des Begrenzungsrahmens der berlappungswurzel hinzugefgt werden, um die endgltigen Wurzel-berlappungsgrenzen zu erzeugen (die in IntersectionObserverEntry.rootBounds offengelegt werden, wenn der Callback ausgefhrt wird). Positive Werte vergrern den Rahmen, whrend negative Werte ihn verkleinern. Jeder Offsetwert kann nur in Pixeln (px) oder Prozent (%) ausgedrckt werden.
Der Effekt, den Rahmen durch den Wurzelabstand zu vergrern, besteht darin, berlaufziele zu ermglichen, mit der Wurzel zu berschneiden, bevor sie sichtbar werden. Dies kann beispielsweise verwendet werden, um mit dem Laden von Bildern kurz bevor sie in den Sichtbereich kommen zu beginnen, anstatt zu dem Zeitpunkt, an dem sie sichtbar werden.
Im folgenden Beispiel haben wir ein scrollbares Feld und ein Element, das zunchst nicht sichtbar ist. Sie knnen den rechten Wurzelabstand anpassen und sehen, dass:
<div class="demo">
<div id="container">
<div id="elem"></div>
<div id="gutter"></div>
</div>
<div id="marginIndicator"></div>
</div>
<div class="controls">
<label>
Set the right margin of the root:
<input id="margin" type="number" value="0" step="5" />px
</label>
<label>
You can also use this slider to scroll the container:
<input id="scrollAmount" type="range" min="0" max="300" value="0" />
</label>
<p>Current intersection ratio: <span id="output"></span></p>
</div>
.demo {
display: flex;
}
.controls {
display: flex;
flex-direction: column;
}
#container {
position: relative;
width: 200px;
height: 100px;
overflow-x: scroll;
border: 1px solid black;
}
#marginIndicator {
position: relative;
height: 100px;
background-color: blue;
opacity: 0.5;
}
#elem {
background-color: red;
width: 100px;
height: 100px;
position: absolute;
left: 200px;
}
#gutter {
width: 500px;
height: 100px;
}
let observer;
function createObserver() {
if (observer) {
observer.disconnect();
}
observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
output.textContent = entry.intersectionRatio.toFixed(2);
});
},
{
threshold: Array.from({ length: 1000 }, (_, i) => i / 1000),
root: container,
rootMargin: `0px ${margin.value}px 0px 0px`,
},
);
if (margin.valueAsNumber < 0) {
marginIndicator.style.width = `${-margin.valueAsNumber}px`;
marginIndicator.style.left = `${margin.valueAsNumber}px`;
marginIndicator.style.backgroundColor = "blue";
} else {
marginIndicator.style.width = `${margin.valueAsNumber}px`;
marginIndicator.style.left = "0px";
marginIndicator.style.backgroundColor = "green";
}
observer.observe(elem);
}
createObserver();
margin.addEventListener("input", () => {
createObserver();
});
scrollAmount.addEventListener("input", () => {
container.scrollLeft = scrollAmount.value;
});
Betrachten Sie den Fall, in dem Sie ein Wurzelelement haben, das geschachtelte Scrollcontainer enthlt und Sie berschneidungen mit einem Ziel innerhalb eines dieser scrollbaren Container beobachten mchten. berschneidungen mit dem Zielelement sind standardmig beobachtbar, wenn das Ziel innerhalb des durch die Wurzel definierten Bereichs sichtbar ist; mit anderen Worten, wenn der Container in der Wurzel in den Sichtbereich gescrollt wird und das Ziel innerhalb des Clipping-Rechtecks seines Containers in den Sichtbereich gescrollt wird.
Sie knnen einen Scrollabstand verwenden, um berschneidungen zu beginnen, bevor oder nachdem das Ziel innerhalb seines Scrollcontainers in den Sichtbereich gescrollt wird. Der Abstand wird zu allen geschachtelten Scrollcontainern in der Wurzel hinzugefgt, einschlielich des Wurzelelements, wenn es auch ein Scrollcontainer ist, und hat den Effekt, entweder die Clippingregion (positive Abstnde) zu vergrern oder zu verkleinern (negative Abstnde), die zum Berechnen von berschneidungen verwendet wird.
Hinweis: Sie knnten einen Intersection Observer an jedem Scrollcontainer erstellen, fr den Sie einen Scrollabstand haben mchten, und die Rootmargin-Eigenschaft verwenden, um einen hnlichen Effekt zu erzielen. Das Verwenden eines Scrollabstands ist ergonomischer, da Sie in den meisten Fllen nur einen Intersection Observer fr alle geschachtelten Ziele haben knnen.
Im folgenden Beispiel haben wir ein scrollbares Feld und ein Bildkarussell, das zunchst aus dem Sichtbereich ist. Ein Beobachter auf dem Wurzelelement beobachtet die Bildzielobjekte innerhalb des Karussells. Wenn ein Bildelement beginnt, sich mit dem Wurzelelement zu berschneiden, wird das Bild geladen, die berschneidung protokolliert und der Beobachter entfernt.
Scrollen Sie nach unten, um das Karussell anzuzeigen. Die sichtbaren Bilder sollten sofort geladen werden. Wenn Sie das Karussell scrollen, sollten Sie feststellen, dass die Bilder geladen werden, sobald das Element sichtbar wird.
Nach dem Zurcksetzen des Beispiels knnen Sie die bereitgestellte Kontrolle verwenden, um den Prozentsatz des Scrollabstands zu ndern. Wenn Sie einen positiven Wert wie 20 % einstellen, wird das Clip-Rechteck des Scrollcontainers um 20 % vergrert und Sie sollten beobachten, dass Bilder erkannt und geladen werden, bevor sie in den Sichtbereich kommen. Ebenso bedeutet ein negativer Wert, dass die berschneidung erkannt wird, sobald Bilder bereits im Sichtbereich sind.
<button id="reset" type="button">Reset</button>
<div id="root-container">
<p>content before (scroll down to carousel)</p>
<div class="flex-container">
<div class="carousel">
<img
src=""
data-src="ballon-portrait.jpg"
class="lazy-carousel-img"
alt="Balloon portrait" />
<img
src=""
data-src="balloon-small.jpg"
class="lazy-carousel-img"
alt="balloon-small" />
<img
src=""
data-src="surfer.jpg"
class="lazy-carousel-img"
alt="surfer" />
<img
src=""
data-src="border-diamonds.png"
class="lazy-carousel-img"
alt="border-diamonds" />
<img src="" data-src="fire.png" class="lazy-carousel-img" alt="fire" />
<img
src=""
data-src="puppy-header.jpg"
class="lazy-carousel-img"
alt="puppy" />
<img src="" data-src="moon.jpg" class="lazy-carousel-img" alt="moon" />
<img src="" data-src="rhino.jpg" class="lazy-carousel-img" alt="rhino" />
</div>
<div id="margin-indicator"></div>
</div>
<p>content after</p>
</div>
<div class="controls">
<label>
Set the right margin of the scroll root:
<input id="margin" type="number" value="0" step="5" />%
</label>
</div>
<pre id="log"></pre>
#root-container {
height: 250px;
overflow-y: auto;
border: solid blue;
}
.controls {
margin-top: 10px;
}
p {
height: 50vh;
}
.flex-container {
display: flex;
}
#margin-indicator {
position: relative;
height: 100px;
width: 1px;
background-color: red;
opacity: 0.5;
display: flex;
}
.carousel {
width: 300px;
overflow-x: auto;
scroll-snap-type: x mandatory;
display: flex;
border: solid;
/* outline: 200px solid rgba(0, 0, 0, 0.1); */
}
.carousel img {
scroll-snap-stop: always;
scroll-snap-align: start;
display: block;
width: 195px;
height: 99px;
min-width: 195px;
min-height: 99px;
margin-right: 10px;
background-color: #eeeeee; /* Placeholder background */
}
#log {
height: 100px;
overflow: scroll;
padding: 0.5rem;
border: 1px solid black;
}
const reload = document.querySelector("#reset");
reload.addEventListener("click", () => {
window.location.reload(true);
});
const logElement = document.querySelector("#log");
function log(text) {
logElement.innerText = `${logElement.innerText}${text}\n`;
logElement.scrollTop = logElement.scrollHeight;
}
const rootContainer = document.getElementById("root-container");
const marginIndicator = document.getElementById("margin-indicator");
const carousel = document.querySelector(".carousel");
const lazyImages = carousel.querySelectorAll(".lazy-carousel-img");
let imageObserver;
function createImageObserver() {
if (imageObserver) {
imageObserver.disconnect();
}
let observerOptions = {
root: rootContainer,
rootMargin: "0px", // No extra margin
scrollMargin: `${margin.valueAsNumber}%`, // No extra margin / Can be set
threshold: 0.01, // Trigger when 1% of the image is visible
};
imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
log(`intersect: ${img.dataset.src}`); // Only on first intersection
img.src = `https://mdn.github.io/shared-assets/images/examples/${img.dataset.src}`; // Load image by setting src
img.classList.remove("lazy-carousel-img"); // Remove the class
observer.unobserve(img); // Stop observing once loaded
}
});
}, observerOptions);
if (margin.valueAsNumber < 0) {
marginIndicator.style.width = `${-margin.valueAsNumber}px`;
marginIndicator.style.left = `${margin.valueAsNumber}px`;
marginIndicator.style.backgroundColor = "blue";
} else {
marginIndicator.style.width = `${margin.valueAsNumber}px`;
marginIndicator.style.left = "0px";
marginIndicator.style.backgroundColor = "green";
}
lazyImages.forEach((image) => {
imageObserver.observe(image); // Start observing each image
});
}
if ("IntersectionObserver" in window) {
createImageObserver();
margin.addEventListener("input", () => {
createImageObserver();
});
} else {
// Fallback for browsers that don't support Intersection Observer
// Loads all images immediately if Intersection Observer is not supported.
lazyImages.forEach((img) => {
img.src = img.dataset.src;
img.classList.remove("lazy-carousel-img");
});
console.warn(
"Intersection Observer not supported. All carousel images loaded.",
);
}
Anstatt jede minimale nderung in der Sichtbarkeit eines Zielelements zu melden, verwendet die Intersection Observer API Schwellenwerte. Wenn Sie einen Beobachter erstellen, knnen Sie einen oder mehrere numerische Werte angeben, die den Prozentsatz des Zielelements darstellen, der sichtbar ist. Die API meldet dann nur nderungen der Sichtbarkeit, die diese Schwellenwerte berschreiten.
Wenn Sie beispielsweise jedes Mal informiert werden mchten, wenn die Sichtbarkeit eines Ziels rckwrts oder vorwrts durch jeden 25 %-Marke geht, wrden Sie das Array [0, 0.25, 0.5, 0.75, 1] als die Liste der Schwellenwerte angeben, wenn Sie den Beobachter erstellen.
Wenn der Callback aufgerufen wird, erhlt er eine Liste von IntersectionObserverEntry-Objekten, eines fr jedes beobachtete Ziel, dessen Grad an berschneidung mit der Wurzel sich so gendert hat, dass der freigelegte Anteil einen der Schwellenwerte in irgendeine Richtung berschreitet.
Sie knnen sehen, ob das Ziel derzeit die Wurzel berschneidet, indem Sie die isIntersecting-Eigenschaft des Eintrags betrachten; wenn sein Wert true ist, berschneidet das Ziel mindestens teilweise das Wurzelelement oder Dokument. Auf diese Weise knnen Sie feststellen, ob der Eintrag einen bergang von der berschneidung der Elemente zum Nicht-berschneiden oder einen bergang vom Nicht-berschneiden zur berschneidung darstellt.
Beachten Sie, dass es mglich ist, ein Null-berschneidungsrechteck zu haben, was passieren kann, wenn die berschneidung genau entlang der Grenze zwischen den beiden liegt oder die Flche von boundingClientRect Null ist. Dieser Zustand, dass das Ziel und die Wurzel eine Grenzlinie teilen, wird nicht als ausreichend betrachtet, um als bergang in einen sich berschneidenden Zustand betrachtet zu werden.
Um ein Gefhl dafr zu bekommen, wie Schwellenwerte funktionieren, versuchen Sie, die Box unten herum zu scrollen. Jede farbige Box darin zeigt den Prozentsatz ihrer selbst, der in allen vier Ecken ihrer sichtbar ist, sodass Sie sehen knnen, wie sich diese Verhltnisse im Laufe der Zeit ndern, whrend Sie den Container scrollen. Jede Box hat eine andere Menge an Schwellenwerten:
IntersectionObserver.thresholds Array ist [0.00, 0.01, 0.02, /*,*/ 0.99, 1.00].<template id="boxTemplate">
<div class="sampleBox">
<div class="label topLeft"></div>
<div class="label topRight"></div>
<div class="label bottomLeft"></div>
<div class="label bottomRight"></div>
</div>
</template>
<main>
<div class="contents">
<div class="wrapper"></div>
</div>
</main>
.contents {
position: absolute;
width: 700px;
height: 1725px;
}
.wrapper {
position: relative;
top: 600px;
}
.sampleBox {
position: relative;
left: 175px;
width: 150px;
background-color: rgb(245 170 140);
border: 2px solid rgb(201 126 17);
padding: 4px;
margin-bottom: 6px;
}
#box1 {
height: 200px;
}
#box2 {
height: 75px;
}
#box3 {
height: 150px;
}
#box4 {
height: 100px;
}
.label {
font:
14px "Open Sans",
"Arial",
sans-serif;
position: absolute;
margin: 0;
background-color: rgb(255 255 255 / 70%);
border: 1px solid rgb(0 0 0 / 70%);
width: 3em;
height: 18px;
padding: 2px;
text-align: center;
}
.topLeft {
left: 2px;
top: 2px;
}
.topRight {
right: 2px;
top: 2px;
}
.bottomLeft {
bottom: 2px;
left: 2px;
}
.bottomRight {
bottom: 2px;
right: 2px;
}
let observers = [];
startup = () => {
const wrapper = document.querySelector(".wrapper");
const template = document.querySelector("#boxTemplate");
// Options for the observers
const observerOptions = {
root: null,
rootMargin: "0px",
threshold: [],
};
// An array of threshold sets for each of the boxes. The
// first box's thresholds are set programmatically
// since there will be so many of them (for each percentage
// point).
const thresholdSets = [
[],
[0.5],
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
[0, 0.25, 0.5, 0.75, 1.0],
];
for (let i = 0; i <= 1.0; i += 0.01) {
thresholdSets[0].push(i);
}
// Add each box, creating a new observer for each
for (let i = 0; i < 4; i++) {
const newBox = document.importNode(template.content, true);
const boxID = `box${i + 1}`;
newBox.querySelector(".sampleBox").id = boxID;
wrapper.appendChild(newBox);
// Set up the observer for this box
observerOptions.threshold = thresholdSets[i];
observers[i] = new IntersectionObserver(
intersectionCallback,
observerOptions,
);
observers[i].observe(document.querySelector(`#${boxID}`));
}
// Scroll to the starting position
document.scrollingElement.scrollTop =
wrapper.firstElementChild.getBoundingClientRect().top + window.scrollY;
document.scrollingElement.scrollLeft = 750;
};
intersectionCallback = (entries) => {
entries.forEach((entry) => {
const box = entry.target;
const visiblePct = `${Math.floor(entry.intersectionRatio * 100)}%`;
box.querySelector(".topLeft").textContent = visiblePct;
box.querySelector(".topRight").textContent = visiblePct;
box.querySelector(".bottomLeft").textContent = visiblePct;
box.querySelector(".bottomRight").textContent = visiblePct;
});
};
startup();
Standardmig liefert der Beobachter Benachrichtigungen, wenn das Zielelement in den Viewport des Wurzelelements gescrollt wird. Whrend dies in vielen Situationen alles ist, was bentigt wird, ist es manchmal wichtig, dass berschneidungen nicht gemeldet werden, wenn das Ziel "optisch kompromittiert" wurde. Beispielsweise ist es wichtig, bei der Messung von Analysen oder Werbesichtungen, dass Zielelemente nicht versteckt oder verzerrt werden, ganz oder teilweise.
Die Option trackVisibility sagt dem Beobachter, nur berschneidungen fr Ziele zu melden, die der Browser nicht fr optisch kompromittiert hlt, wie durch das ndern der Deckkraft oder das Anwenden eines Filters oder einer Transformation.
Der Algorithmus ist konservativ und kann Elemente weglassen, die technisch sichtbar sind, wie die mit nur einer geringfgigen Deckkraftreduzierung.
Die Sichtbarkeitsberechnung ist rechnerisch teuer und sollte nur verwendet werden, wenn sie bentigt wird.
Beim Verfolgen der Sichtbarkeit sollte auch eine delay eingestellt werden, um die minimale Berichtsperiode zu begrenzen.
Die Empfehlung ist, die Verzgerung auf den grten tolerierbaren Wert einzustellen (die minimale Verzgerung beim Verfolgen der Sichtbarkeit betrgt 100 Millisekunden).
Der Browser berechnet das endgltige berschneidungsrechteck wie folgt; dies wird alles fr Sie erledigt, aber es kann hilfreich sein, diese Schritte zu verstehen, um besser zu begreifen, wann berschneidungen auftreten werden.
getBoundingClientRect() auf dem Ziel abgerufen. Dies ist das grte, das das berschneidungsrechteck sein kann. Die verbleibenden Schritte werden alle nicht berschneidenden Anteile entfernen.overflow-Eigenschaft angegeben wird, bestimmt. Das Setzen von overflow auf alles auer visible fhrt zum Clipping.<iframe> enthalten ist), wird das berschneidungsrechteck auf den Viewport des enthaltenden Kontexts zugeschnitten, und die Rekursion nach oben durch die Container wird mit dem enthaltenen Block des Containers fortgesetzt. Wenn also die oberste Ebene eines <iframe> erreicht wird, wird das berschneidungsrechteck auf den Viewport des Rahmens zugeschnitten, dann ist das bergeordnete Element des Rahmens der nchste Block, der rekursiv zur berlappungswurzel durchlaufen wird.IntersectionObserverDie primre Schnittstelle fr die Intersection Observer API. Bietet Methoden zum Erstellen und Verwalten eines Beobachters, der nderungen in der berschneidung zwischen einem oder mehreren Zielelementen und einem gemeinsamen Vorfahrenelement oder dem Viewport ihres obersten Dokuments asynchron beobachten kann. Der Vorfahre oder der Viewport wird als Wurzel bezeichnet.
IntersectionObserverEntryBeschreibt die berschneidung zwischen dem Zielelement und seinem Wurzelcontainer zu einem bestimmten bergangsmoment. Objekte dieses Typs knnen nur auf zwei Arten abgerufen werden: als Eingabe fr Ihren IntersectionObserver-Callback oder durch den Aufruf von IntersectionObserver.takeRecords().
Dieses einfache Beispiel lsst ein Zielelement seine Farbe und Transparenz ndern, wenn es mehr oder weniger sichtbar wird. Bei Timing der Elementsichtbarkeit mit der Intersection Observer API finden Sie ein ausfhrlicheres Beispiel, das zeigt, wie lange ein Satz von Elementen (wie Anzeigen) fr den Benutzer sichtbar ist, und darauf reagiert, indem Statistiken aufzeichnen oder Elemente aktualisiert werden.
Das HTML fr dieses Beispiel ist sehr kurz, mit einem primren Element, das die Box ist, die wir anvisieren werden (mit der kreativen ID "box"), und einigen Inhalten innerhalb der Box.
<div id="box">
<div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>
Das CSS ist fr die Zwecke dieses Beispiels nicht besonders wichtig; es legt das Element aus und stellt sicher, dass die Attribute background-color und border an CSS-bergngen teilnehmen knnen, die wir verwenden werden, um die nderungen am Element zu bewirken, wenn es mehr oder weniger verdeckt wird.
#box {
background-color: rgb(40 40 190 / 100%);
border: 4px solid rgb(20 20 120);
transition:
background-color 1s,
border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.vertical {
color: white;
font: 32px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(20 20 120);
text-align: center;
padding: 20px;
}
Schlielich werfen wir einen Blick auf den JavaScript-Code, der die Intersection Observer API verwendet, um Dinge geschehen zu lassen.
Zuerst mssen wir einige Variablen vorbereiten und den Observer installieren.
const numSteps = 20.0;
const boxElement = document.querySelector("#box");
let prevRatio = 0.0;
let increasingColor = "rgb(40 40 190 / ratio)";
let decreasingColor = "rgb(190 40 40 / ratio)";
createObserver();
Die Konstanten und Variablen, die wir hier einrichten, sind:
numStepsEine Konstante, die angibt, wie viele Schwellenwerte wir zwischen einem Sichtbarkeitsverhltnis von 0,0 und 1,0 haben mchten.
prevRatioDiese Variable wird verwendet, um zu erfassen, was das Sichtbarkeitsverhltnis beim letzten berschreiten eines Schwellenwerts war; dies ermglicht es uns herauszufinden, ob das Zielelement mehr oder weniger sichtbar wird.
increasingColorEin String, der eine Farbe definiert, die wir auf das Zielelement anwenden werden, wenn das Sichtbarkeitsverhltnis steigt. Das Wort "ratio" in diesem String wird durch das aktuelle Sichtbarkeitsverhltnis des Ziels ersetzt, damit das Element nicht nur die Farbe ndert, sondern auch zunehmend deckend wird, wenn es weniger verdeckt wird.
decreasingColorEbenso ist dies ein String, der eine Farbe definiert, die wir anwenden, wenn das Sichtbarkeitsverhltnis sinkt.
Wir erhalten eine Referenz auf das Element mit der ID "box" mit querySelector() und rufen dann die Methode createObserver() auf, die wir gleich erstellen werden, um die Erstellung und Installation des Intersection Observer zu behandeln.
Die Methode createObserver() wird nach dem Laden der Seite einmal aufgerufen, um den neuen IntersectionObserver tatschlich zu erstellen und den Beobachtungsprozess fr das Zielelement zu starten.
function createObserver() {
const options = {
root: null,
rootMargin: "0px",
threshold: buildThresholdList(),
};
const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(boxElement);
}
Dies beginnt mit dem Einrichten eines options-Objektes, das die Einstellungen fr den Observer enthlt. Wir mchten nderungen der Sichtbarkeit des Zielelements relativ zum Dokumentenviewport beobachten, also ist root null. Wir bentigen keine Marge, daher wird die Margenverschiebung, rootMargin, als "0px" angegeben. Dies fhrt dazu, dass der Beobachter nderungen in der berschneidung zwischen den Grenzen des Zielelements und denen des Viewports beobachtet, ohne dass zustzlicher (oder subtrahierter) Platz entsteht.
Die Liste der Schwellenwerte fr das Sichtbarkeitsverhltnis, threshold, wird durch die Funktion buildThresholdList() erstellt. Die Schwellenwertliste wird in diesem Beispiel programmgesteuert erstellt, da es mehrere davon gibt und die Anzahl anpassbar sein soll.
Sobald options bereit ist, erstellen wir den neuen Beobachter, indem wir den Konstruktor IntersectionObserver() aufrufen und eine Funktion spezifizieren, die aufgerufen wird, wenn eine berschneidung einen unserer Schwellenwerte berschreitet, handleIntersect(), und unser Set von Optionen. Dann rufen wir observe() auf dem zurckgegebenen Beobachter auf und bergeben ihm das gewnschte Zielelement.
Wir knnten uns entscheiden, mehrere Elemente auf Sichtbarkeitsberschneidungsnderungen im Hinblick auf den Viewport zu berwachen, indem wir observer.observe() fr jedes dieser Elemente aufrufen, wenn wir dies tun wollten.
Die Funktion buildThresholdList(), die die Liste der Schwellenwerte erstellt, sieht so aus:
function buildThresholdList() {
const thresholds = [];
const numSteps = 20;
for (let i = 1.0; i <= numSteps; i++) {
const ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
Dies baut das Array der Schwellenwerte auf jeder davon ist ein Verhltnis zwischen 0,0 und 1,0, indem der Wert i/numSteps fr jede ganze Zahl i zwischen 1 und numSteps in das thresholds-Array eingefgt wird. Es wird auch 0 hinzugefgt, um diesen Wert zu enthalten. Das Ergebnis, angesichts des Standardwerts von numSteps (20), ist die folgende Liste von Schwellenwerten:
| # | Verhltnis | # | Verhltnis |
|---|---|---|---|
| 0 | 0.05 | 11 | 0.6 |
| 1 | 0.1 | 12 | 0.65 |
| 2 | 0.15 | 13 | 0.7 |
| 3 | 0.2 | 14 | 0.75 |
| 4 | 0.25 | 15 | 0.8 |
| 5 | 0.3 | 16 | 0.85 |
| 6 | 0.35 | 17 | 0.9 |
| 7 | 0.4 | 18 | 0.95 |
| 8 | 0.45 | 19 | 1 |
| 9 | 0.5 | 20 | 0 |
| 10 | 0.55 |
Wir knnten natrlich das Array der Schwellenwerte in unseren Code fest einprogrammieren, und oft werden Sie genau das tun. Aber dieses Beispiel lsst Raum fr das Hinzufgen von Steuerungen zur Anpassung der Granularitt, zum Beispiel.
Wenn der Browser erkennt, dass das Zielelement (in unserem Fall das mit der ID "box") enthllt oder verdeckt wurde, sodass sein Sichtbarkeitsverhltnis einen unserer Schwellenwerte in unserer Liste berschreitet, ruft er unsere Handlerfunktion handleIntersect() auf:
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.backgroundColor = increasingColor.replace(
"ratio",
entry.intersectionRatio,
);
} else {
entry.target.style.backgroundColor = decreasingColor.replace(
"ratio",
entry.intersectionRatio,
);
}
prevRatio = entry.intersectionRatio;
});
}
Fr jedes IntersectionObserverEntry in der Liste entries schauen wir, ob das intersectionRatio des Eintrags steigt. Wenn es steigt, setzen wir die background-color des Ziels auf den String in increasingColor (denken Sie daran, es ist "rgb(40 40 190 / ratio)"), ersetzen das Wort "ratio" mit dem intersectionRatio des Eintrags. Das Ergebnis: Das Ziel ndert nicht nur die Farbe, sondern auch die Transparenz; wenn das berschneidungsverhltnis sinkt, sinkt der Alphawert der Hintergrundfarbe, was zu einem Element fhrt, das mehr transparent wird.
Ebenso, wenn das intersectionRatio sinkt, verwenden wir den String decreasingColor und ersetzen das Wort "ratio" durch das intersectionRatio, bevor wir die background-color des Zielelements setzen.
Schlielich merken wir uns, um zu verfolgen, ob das berschneidungsverhltnis steigt oder sinkt, das aktuelle Verhltnis in der Variable prevRatio.
Unten ist das resultierende Inhalt. Scrollen Sie diese Seite nach oben und unten und bemerken Sie, wie sich das Erscheinungsbild der Box verndert, whrend Sie dies tun.
Es gibt ein noch umfangreicheres Beispiel bei Timing der Elementsichtbarkeit mit der Intersection Observer API.
| Spezifikation |
|---|
| Intersection Observer # intersection-observer-interface |
IntersectionObserver und IntersectionObserverEntryDer Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |