| [ 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, nderungen in der berlappung eines Zielelements mit einem Vorfahrelement oder mit dem Viewport eines obersten Dokuments asynchron zu beobachten.
Historisch gesehen war das Ermitteln 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 Webseiten, auf die der Nutzer zugreift, zu verlangsamen. Mit der Reife des Webs ist der Bedarf an dieser Art von Informationen gewachsen. Informationen ber die berlappung werden aus vielen Grnden bentigt, wie zum Beispiel:
Frher erforderte die Implementierung der berlappungserkennung das Hinzufgen von Event-Handlern und Schleifen, die Methoden wie Element.getBoundingClientRect() aufrufen, um die bentigten Informationen fr jedes betroffene Element zu sammeln. Da dieser gesamte Code auf dem Hauptthread ausgefhrt wird, kann sogar ein einziges Ereignis Leistungsprobleme verursachen. Wenn eine Webseite mit diesen Tests beladen ist, knnen die Dinge richtig unschn werden.
Betrachten Sie eine Webseite, die unendliches Scrollen verwendet. Sie verwendet eine von einem Anbieter bereitgestellte Bibliothek, um die auf der Seite periodisch platzierten Anzeigen zu verwalten, hat animierte Grafiken hier und da und verwendet eine benutzerdefinierte Bibliothek, die Benachrichtigungsboxen und hnliches zeichnet. Jede dieser Komponenten hat ihre eigenen Routinen zur Erkennung der berlappung, die alle auf dem Hauptthread laufen. Der Autor der Website bemerkt mglicherweise nicht einmal, dass dies passiert, da er mglicherweise nur sehr wenig ber die inneren Ablufe der beiden verwendeten Bibliotheken wei. Whrend der Benutzer die Seite scrollt, feuern diese Routinen zur Erkennung der berlappung stndig whrend des Scroll-Codes, was zu einer Erfahrung fhrt, die den Benutzer frustriert zurcklsst, sowohl mit dem Browser als auch mit der Webseite und seinem Computer.
Die Intersection Observer API ermglicht es, eine Callback-Funktion zu registrieren, die jedes Mal ausgefhrt wird, wenn ein bestimmtes Element eine berlappung mit einem anderen Element (oder dem Viewport) betritt oder verlsst, oder wenn sich die berlappung zwischen zwei Elementen um einen bestimmten Betrag ndert. Auf diese Weise mssen Websites nichts mehr auf dem Hauptthread tun, um diese Art der Elementberlappung zu beobachten, und der Browser kann die Verwaltung der berlappungen optimieren, wie es ihm am besten erscheint.
Eine Sache, die die Intersection Observer API nicht kann: Logik basierend auf der genauen Anzahl von Pixeln auszulsen, die sich berlappen, oder spezifisch basierend darauf, welche es sind. Sie lst nur den allgemeinen Anwendungsfall "Wenn sie sich irgendwo um N% berlappen, muss ich etwas tun" aus.
Die Intersection Observer API ermglicht es Ihnen, einen Callback zu konfigurieren, der aufgerufen wird, wenn einer dieser Umstnde eintritt:
Normalerweise mchten Sie berlappungsnderungen in Bezug auf den nchsten scrollbaren Vorfahren des Zielelements beobachten oder, wenn das Zielelement kein Nachfahre eines scrollbaren Elements ist, den Viewport des Gerts verwenden. Um berlappungen relativ zum Viewport des Gerts zu beobachten, geben Sie null fr die Option root an. Lesen Sie weiter fr eine detailliertere Erklrung der Optionen des Intersection Observers.
Unabhngig davon, ob Sie den Viewport oder ein anderes Element als Wurzel verwenden, funktioniert die API 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 berlappung mit der Wurzel kreuzt.
Der Grad der berlappung zwischen dem Zielelement und seiner Wurzel ist das berlappungsverhltnis. Dies ist eine Darstellung des Prozentsatzes des Zielelements, das als Wert zwischen 0.0 und 1.0 sichtbar ist.
Erstellen Sie den Intersection Observer, indem Sie seinen Konstruktor aufrufen und ihm eine Callback-Funktion bergeben, die 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 der Callback ausgelst wird, wenn 100 % des Ziels innerhalb des Elements sichtbar sind, das durch die root Option angegeben ist.
Das bergeordnete Objekt, das an den Konstruktor IntersectionObserver() bergeben wird, ermglicht es Ihnen, die Umstnde zu kontrollieren, unter denen der Callback des Observers ausgelst 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 wie die CSS-Eigenschaft margin, z. B. "10px 20px 30px 40px" (oben, rechts, unten, links). Die Werte knnen nur in Pixeln (px) oder Prozent (%) angegeben werden. Dieses Set von Werten dient dazu, jede Seite des Begrenzungsrahmens des Wurzelelements vor der Berechnung der berlappungen zu vergrern oder zu verkleinern. Negative Werte verkleinern den Begrenzungsrahmen des Wurzelelements und positive Werte erweitern ihn. Der Standardwert, wenn nicht angegeben, ist "0px 0px 0px 0px".
scrollMarginRand um die verschachtelten scrolling containers, der die gleichen Werte annimmt/die gleichen Standardwerte hat wie rootMargin.
Die Rnder werden auf verschachtelte scrollbare Container angewendet, bevor berlappungen berechnet werden.
Positive Werte vergrern das Clipping-Rechteck des Containers, sodass Ziele berlappen knnen, bevor sie sichtbar werden, 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 sollte. Wenn Sie nur feststellen mchten, wann die Sichtbarkeit die Grenze von 50 % berschreitet, knnen Sie einen Wert von 0,5 verwenden. Wenn Sie mchten, dass der Callback jedes Mal ausgefhrt wird, wenn die Sichtbarkeit um weitere 25 % berschreitet, wrden Sie das Array [0, 0.25, 0.5, 0.75, 1] spezifizieren. Der Standardwert ist 0 (was bedeutet, dass der Callback ausgefhrt wird, sobald das Zielelement die Grenze der Wurzel berlappt oder berhrt, auch wenn noch keine Pixel sichtbar sind). Ein Wert von 1.0 bedeutet, dass der Schwellenwert nicht als berschritten angesehen wird, bis jedes Pixel sichtbar ist.
delay Wenn Sie die Sichtbarkeit eines Ziels verfolgen (trackVisibility ist true), kann dies verwendet werden, um die Mindestverzgerung in Millisekunden zwischen Benachrichtigungen von diesem Observer festzulegen.
Die Begrenzung der Benachrichtigungsrate ist wnschenswert, da die Berechnung der Sichtbarkeit rechenintensiv ist.
Wenn Sie die Sichtbarkeit verfolgen, wird der Wert auf 100 festgelegt, wenn ein Wert unter 100 liegt, und Sie sollten den grten ertrglichen Wert verwenden.
Der Standardwert ist 0.
trackVisibility Ein boolesches Wert, das angibt, ob dieser IntersectionObserver nderungen in der Sichtbarkeit eines Ziels verfolgt.
Wenn false, meldet der Browser berlappungen, wenn das Zielelement in den Viewport des Wurzelelements scrollt.
Wenn true, berprft der Browser zustzlich, ob das Ziel tatschlich sichtbar ist, und nicht durch andere Elemente verdeckt oder mglicherweise durch ein Filter, reduzierte Deckkraft oder eine Transformation verzerrt oder verborgen wurde.
Der Standardwert ist false, da das Verfolgen der Sichtbarkeit rechenintensiv ist.
Wenn dies eingestellt ist, sollte auch eine delay festgelegt werden.
Der Callback, der dem Konstruktor IntersectionObserver() bergeben wird, 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 umfasst ein IntersectionObserverEntry Objekt fr jedes Ereignis beim berschreiten eines Schwellenwerts es knnen mehrere Eintrge gleichzeitig empfangen werden, entweder von mehreren Zielen oder von einem einzigen Ziel, das mehrere Schwellenwerte in kurzer Zeit berschreitet. Die Eintrge werden mit einer Warteschlange bermittelt, sodass sie nach dem Zeitpunkt, zu dem sie generiert wurden, geordnet sein sollten. Sie sollten jedoch vorzugsweise IntersectionObserverEntry.time verwenden, um sie korrekt zu ordnen. Jeder Eintrag beschreibt, wie viel eines gegebenen Elements mit dem Wurzelelement berlappt, ob das Element als berlappend betrachtet wird oder nicht, usw. Der Eintrag enthlt nur Informationen ber diesen besonderen Moment wenn Sie Informationen bentigen, die eine Verfolgung im Laufe der Zeit erfordern, wie die Scrollrichtung und -geschwindigkeit, mssen Sie diese mglicherweise selbst berechnen, indem Sie zuvor empfangene Eintrge speichern.
Seien Sie sich bewusst, dass Ihr Callback auf dem Hauptthread ausgefhrt wird. Er sollte so schnell wie mglich arbeiten; wenn etwas zeitaufwndiges erledigt werden muss, verwenden Sie Window.requestIdleCallback().
Der folgende Codeausschnitt zeigt einen Callback, der einen Zhler fhrt, wie oft Elemente von einer Nicht-berlappung mit der Wurzel zu einer berlappung von mindestens 75% wechseln. Bei einem Schwellenwert von 0.0 (Standard) wird der Callback ungefhr bei der bergabe des booleschen Werts von isIntersecting aufgerufen. Der Ausschnitt berprft daher zunchst, ob der bergang ein positiver ist, und ermittelt dann, ob intersectionRatio ber 75% liegt, in welchem Fall der Zhler erhht wird.
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 geben:
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 ausgelst.
Beachten Sie auch, dass das Ziel ein Nachfahre des Wurzelelements sein muss, wenn Sie die root Option angegeben haben.
Alle von der Intersection Observer API betrachteten Bereiche sind Rechtecke; Elemente, die unregelmig geformt sind, werden als belegt durch das kleinste Rechteck angesehen, das alle Teile des Elements einschliet. Auch wenn der sichtbare Teil eines Elements nicht rechteckig ist, wird das berlappungsrechteck des Elements als das kleinste Rechteck angesehen, das alle sichtbaren Teile des Elements enthlt.
Es ist ntzlich, ein wenig darber zu verstehen, wie die verschiedenen von IntersectionObserverEntry bereitgestellten Eigenschaften eine berlappung beschreiben.
Bevor wir die berlappung eines Elements mit einem Container verfolgen knnen, mssen wir wissen, was dieser Container ist. Dieser Container ist das berlappungselement oder Wurzelelement. Dies kann entweder ein spezifisches Element im Dokument sein, das ein Vorfahre des zu beobachtenden Elements ist, oder null, um den Viewport des Dokuments als Container zu verwenden.
Das Wurzelberlappungsrechteck ist das Rechteck, das verwendet wird, um gegen das Ziel oder die Ziele zu prfen. Dieses Rechteck wird folgendermaen bestimmt:
Document), ist das Wurzelberlappungsrechteck das Rechteck des Viewports.getBoundingClientRect() darauf zurckgegeben wird).Das Wurzelberlappungsrechteck kann weiter angepasst werden, indem der Wurzelrand, rootMargin, beim Erstellen des IntersectionObserver festgelegt wird. Die Werte in rootMargin definieren Offsets, die zu jeder Seite des Begrenzungsrahmens des berlappungselements hinzugefgt werden, um die endgltigen Wurzelberlappungsgrenzen zu erstellen (die bei der Ausfhrung des Callbacks in IntersectionObserverEntry.rootBounds offengelegt werden). Positive Werte erweitern die Box, whrend negative Werte sie verkleinern. Jeder Offsetwert kann nur in Pixeln (px) oder als Prozentsatz (%) ausgedrckt werden.
Der Effekt der Erweiterung der Box mit dem Wurzelrand besteht darin, Ziele berlappen zu lassen, bevor sie sichtbar werden. Dies kann z. B. verwendet werden, um das Laden von Bildern zu starten, kurz bevor sie in den Sichtbereich kommen, anstatt erst, wenn sie sichtbar werden.
Im untenstehenden Beispiel haben wir ein scrollbares Feld und ein Element, das anfangs nicht sichtbar ist. Sie knnen den rechten Rand der Wurzel 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 verschachtelte Scroll-Container enthlt und Sie berlappungen mit einem Ziel innerhalb eines dieser scrollbaren Container beobachten mchten. berlappungen mit dem Zielelement beginnen standardmig dann beobachtbar zu werden, wenn das Ziel innerhalb des vom Wurzel festgelegten Bereichs sichtbar ist; mit anderen Worten, wenn der Container im Wurzelbereich in den Sichtbereich gescrollt wird und das Ziel innerhalb des Clipping-Rechtecks seines Containers gescrollt wird.
Sie knnen einen Scrollrand verwenden, um berlappungen zu beobachten, bevor oder nachdem das Ziel innerhalb seines Scroll-Containers in den Sichtbereich gescrollt wird. Der Rand wird allen verschachtelten Scroll-Containern im Wurzel hinzugefgt, einschlielich des Wurzelelements, wenn es ebenfalls ein Scroll-Container ist, und hat den Effekt, entweder den Clipping-Bereich (positive Rnder) zu vergrern oder (negative Rnder) zu verkleinernd.
Hinweis: Sie knnten einen Intersection Observer auf jedem Scroll-Container erstellen, fr den Sie einen Scroll-Rand wnschen, und die Root-Margin-Eigenschaft verwenden, um einen hnlichen Effekt zu erzielen. Die Verwendung eines Scrollrands ist ergonomischer, da Sie in den meisten Fllen nur einen Intersection Observer fr alle verschachtelten Ziele haben knnen.
Im untenstehenden Beispiel haben wir ein scrollbares Feld und ein anfnglich nicht sichtbares Bild-Karussell. Ein Observer auf dem Wurzelelement beobachtet die Bildelementziele innerhalb des Karussells. Wenn ein Bildelement beginnt, mit dem Wurzelelement zu berlappen, wird das Bild geladen, die berlappung protokolliert und der Observer entfernt.
Scrollen Sie herunter, um das Karussell anzuzeigen. Die sichtbaren Bilder sollten sofort geladen werden. Wenn Sie durch das Karussell scrollen, sollten Sie beobachten, dass die Bilder geladen werden, sobald das Element sichtbar wird.
Nach dem Zurcksetzen des Beispiels knnen Sie die bereitgestellte Steuerung verwenden, um den Scrollrand-Prozentsatz zu ndern. Wenn Sie einen positiven Wert wie 20% einstellen, wird das Clip-Rechteck des Scroll-Containers um 20% vergrert und Sie sollten beobachten, dass Bilder erkannt und geladen werden, bevor sie sichtbar werden. hnlich bedeutet ein negativer Wert, dass die berlappung erkannt wird, wenn 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 unendlich kleine nderung in der Sichtbarkeit eines Zielelements zu melden, verwendet die Intersection Observer API Schwellenwerte. Wenn Sie einen Observer erstellen, knnen Sie eine oder mehrere numerische Werte angeben, die Prozentstze des sichtbaren Zielelements darstellen. Dann berichtet die API nur nderungen der Sichtbarkeit, die diese Schwellenwerte berschreiten.
Zum Beispiel, wenn Sie jedes Mal informiert werden mchten, wenn die Sichtbarkeit eines Ziels rckwrts oder vorwrts durch jede 25% Markierung geht, wrden Sie das Array [0, 0.25, 0.5, 0.75, 1] als Liste der Schwellenwerte bei der Erstellung des Observers angeben.
Wenn der Callback aufgerufen wird, empfngt er eine Liste von IntersectionObserverEntry Objekten, eines fr jedes beobachtete Ziel, dessen Grad der berlappung mit der Wurzel sich so verndert hat, dass die Menge, die freigelegt wird, einen der Schwellenwerte berschreitet, in beide Richtungen.
Sie knnen sehen, ob das Ziel derzeit die Wurzel berlappt, indem Sie die isIntersecting Eigenschaft des Eintrags ansehen; wenn ihr Wert true ist, berlappt das Ziel mindestens teilweise das Wurzelelement oder das Dokument. Dies ermglicht es Ihnen festzustellen, ob der Eintrag einen bergang von der berlappung der Elemente zu einer nicht mehr vorhandenen berlappung oder einen bergang von keiner berlappung zur berlappung darstellt.
Beachten Sie, dass es mglich ist, ein Rechteck ohne berlappung zu haben, was passieren kann, wenn die berlappung genau an der Grenze zwischen den beiden liegt oder die Flche von boundingClientRect null ist. Dieser Zustand, bei dem Ziel und Wurzel eine Grenzlinie teilen, wird nicht als ausreichend betrachtet, um als bergang in einen berlappungszustand angesehen zu werden.
Um ein Gefhl dafr zu bekommen, wie Schwellenwerte funktionieren, versuchen Sie, das untenstehende Feld zu scrollen. Jede farbige Box darin zeigt den Prozentsatz ihrer selbst, die in allen vier Ecken sichtbar ist, an, sodass Sie diese Verhltnisse im Laufe der Zeit ndern knnen, whrend Sie den Container scrollen. Jede Box hat eine unterschiedliche Reihe von 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 bietet der Observer 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 berlappungen nicht gemeldet werden, wenn das Ziel "visuell beeintrchtigt" wurde. Zum Beispiel ist es bei der Messung von Analytik oder Werbeeinblendungen wichtig, dass Zielelemente nicht verborgen oder verzerrt sind, ganz oder teilweise.
Die trackVisibility Einstellung weist den Observer an, nur berlappungen fr Ziele zu melden, die der Browser nicht als visuell beeintrchtigt ansieht, wie durch ndern der Opazitt oder Anwenden eines Filters oder einer Transformation.
Der Algorithmus ist konservativ und kann Elemente weglassen, die technisch sichtbar sind, wie solche mit nur einer leichten Opazittsreduktion.
Die Berechnung der Sichtbarkeit ist rechenintensiv und sollte nur bei Bedarf verwendet werden.
Wenn Sie die Sichtbarkeit verfolgen, sollte auch eine delay festgelegt werden, um das minimale Berichtsintervall zu begrenzen.
Die Empfehlung ist, das Limit auf den grtmglichen Wert einzustellen (die Mindestverzgerung bei der Sichtbarkeitsverfolgung betrgt 100 Millisekunden).
Der Browser berechnet das endgltige berlappungsrechteck wie folgt; all das wird fr Sie erledigt, aber es kann hilfreich sein, diese Schritte zu verstehen, um besser zu begreifen, wann berlappungen auftreten werden.
getBoundingClientRect() auf dem Ziel erhalten.
Dies ist das grte, das das berlappungsrechteck sein kann. Die verbleibenden Schritte entfernen alle Teile, die nicht berlappen.overflow Eigenschaft angegeben wird. Das Festlegen von overflow auf einen Wert auer visible verursacht das Clipping.<iframe> enthalten ist), wird das berlappungsrechteck auf den Viewport des enthaltenen Kontexts beschnitten, und die Rekursion nach oben durch die Container geht mit dem enthaltenden Block des Containers weiter. Wenn also die oberste Ebene eines <iframe> erreicht wird, wird das berlappungsrechteck auf den Viewport des Rahmens zurechtgeschnitten, dann ist das nchste Block in der Rekursion durch den berlappungselement der Elternelement des Rahmens.Dokuments des Ziels abgebildet.IntersectionObserverDie primre Schnittstelle fr die Intersection Observer API. Bietet Methoden zur Erstellung und Verwaltung eines Observers, der jede Anzahl von Zielelementen fr dieselbe berlappungskonfiguration beobachten kann. Jeder Observer kann asynchron nderungen der berlappung zwischen einem oder mehreren Zielelementen und einem gemeinsamen Vorfahrenelement oder mit ihrem obersten Dokument Viewport beobachten. Der Vorfahre oder der Viewport wird als Wurzel bezeichnet.
IntersectionObserverEntryBeschreibt die berlappung zwischen dem Zielelement und seinem Wurzelcontainer zu einem bestimmten bergangsmoment. Objekte dieses Typs knnen nur auf zwei Arten erhalten werden: als Eingabe fr Ihren IntersectionObserver Callback oder durch Aufrufen von IntersectionObserver.takeRecords().
Dieses einfache Beispiel bewirkt, dass sich ein Zielelement in seiner Farbe und Transparenz ndert, whrend es mehr oder weniger sichtbar wird. Bei Timing element visibility with the Intersection Observer API finden Sie ein umfangreicheres Beispiel, das zeigt, wie die Zeit gemessen wird, wie lange eine Gruppe von Elementen (wie Anzeigen) fr den Nutzer sichtbar sind und wie auf diese Informationen reagiert wird, indem Statistiken aufgezeichnet oder Elemente aktualisiert werden.
Das HTML fr dieses Beispiel ist sehr kurz, mit einem primren Element, das die Box ist, die wir anvisieren (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 so an und stellt sicher, dass die Eigenschaften background-color und border an CSS-bergngen teilnehmen knnen, die wir verwenden, um die nderungen am Element zu bewirken, whrend 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.
Zunchst 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 das Sichtbarkeitsverhltnis zu speichern, das beim letzten berschreiten eines Schwellenwerts vorhanden 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, wenn das Sichtbarkeitsverhltnis zunimmt. Das Wort "ratio" in diesem String wird durch das aktuelle Sichtbarkeitsverhltnis des Ziels ersetzt, sodass sich das Element nicht nur farblich ndert, sondern auch zunehmend undurchsichtig wird, wenn es weniger verdeckt wird.
decreasingColorEbenso ist dies ein String, der eine Farbe definiert, die wir verwenden, wenn das Sichtbarkeitsverhltnis abnimmt.
Wir erhalten eine Referenz zu dem Element mit der ID "box" durch querySelector(), dann rufen wir die Methode createObserver() auf, die wir in einem Moment erstellen werden, um den Aufbau und die Installation des Intersection Observers zu handhaben.
Die Methode createObserver() wird einmal nach dem Laden der Seite aufgerufen, um tatschlich den neuen IntersectionObserver zu erstellen und den Prozess der berwachung des Zielelements 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 Objekts, das die Einstellungen fr den Observer enthlt. Wir mchten nderungen in der Sichtbarkeit des Zielelements in Bezug auf den Viewport des Dokuments beobachten, daher ist root null. Wir bentigen keinen Rand, also der Margin-Offset, rootMargin, ist als "0px" angegeben. Dies fhrt dazu, dass der Observer nderungen in der berlappung zwischen den Grenzen des Zielelements und denen des Viewports ohne hinzugefgten (oder subtrahierten) Raum beobachtet.
Die Liste der Sichtbarkeitsverhltnis-Schwellenwerte, threshold, wird durch die Funktion buildThresholdList() erstellt. Die Schwellenwertliste wird in diesem Beispiel programmgesteuert erstellt, da es eine Reihe von ihnen gibt und die Anzahl anpassbar sein soll.
Sobald options bereit ist, erstellen wir den neuen Observer, indem wir den IntersectionObserver() Konstruktor aufrufen, eine Funktion angeben, die aufgerufen wird, wenn eine unserer Schwellenwerte berschritten wird, handleIntersect(), und unser Set von Optionen. Wir rufen dann observe() am zurckgegebenen Observer auf und bergeben ihm das gewnschte Zielelement.
Wir knnten uns entscheiden, mehrere Elemente auf nderungen der Sichtbarkeitsberlappung im Hinblick auf den Viewport zu berwachen, indem wir fr jedes dieser Elemente observer.observe() aufrufen, wenn wir dies tun wollten.
Die Funktion buildThresholdList(), die die Liste der Schwellenwerte erstellt, sieht folgendermaen 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 erstellt das Array von Schwellenwerten - jedes davon ist ein Verhltnis zwischen 0.0 und 1.0, indem der Wert i/numSteps zum thresholds Array fr jede ganze Zahl i zwischen 1 und numSteps hinzugefgt wird. Es fgt auch 0 hinzu, um diesen Wert einzuschlieen. Das Ergebnis, bei dem der Standardwert von numSteps (20) verwendet wird, 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 |
Natrlich knnten wir das Array der Schwellenwerte in unseren Code fest einprogrammieren und oft werden Sie das tun. Aber dieses Beispiel lsst Raum fr die Hinzufgung von Steuerungen, um die Granularitt anzupassen, zum Beispiel.
Wenn der Browser erkennt, dass das Zielelement (in unserem Fall das mit der ID "box") so enthllt oder verdeckt wurde, dass sein Sichtbarkeitsverhltnis einen unserer Schwellenwerte berschreitet, ruft es unsere Handler-Funktion 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 jeden IntersectionObserverEntry in der Liste entries sehen wir nach, ob das intersectionRatio des Eintrags steigt; wenn es so ist, setzen wir das background-color des Ziels auf den String in increasingColor (denken Sie daran, es ist "rgb(40 40 190 / ratio)"), ersetzt das Wort "ratio" durch das intersectionRatio des Eintrags. Das Ergebnis: Nicht nur ndert sich die Farbe, sondern die Transparenz des Zielelements ndert sich ebenfalls; wenn das berlappungsverhltnis sinkt, sinkt der Alphawert der Hintergrundfarbe ebenfalls mit ihm, was zu einem Element fhrt, das durchsichtiger wird.
Ebenso, wenn das intersectionRatio sinkt, verwenden wir den String decreasingColor und ersetzen das Wort "ratio" darin durch das intersectionRatio, bevor wir das background-color des Zielelements setzen.
Schlielich, um zu verfolgen, ob das berlappungsverhltnis steigt oder sinkt, speichern wir das aktuelle Verhltnis in der Variablen prevRatio.
Unten ist der resultierende Inhalt. Scrollen Sie diese Seite nach oben und unten und beachten Sie, wie sich das Erscheinungsbild der Box ndert, whrend Sie dies tun.
Es gibt ein noch umfangreicheres Beispiel bei Timing element visibility with the 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 |