Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

IntersectionObserver: scrollMargin-Eigenschaft

Baseline 2025
Newly available

Since ⁨September 2025⁩, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

Die scrollMargin-Nur-Lese-Eigenschaft des IntersectionObserver-Interfaces fügt einem verschachtelten Scroll-Container innerhalb des Wurzelelements, einschließlich des Wurzelelements selbst, wenn es ein Scroll-Container ist, einen Rand hinzu.

Dies vergrößert oder verkleinert das Clipping-Rechteck der scrollbaren Container, bevor die Schnittpunkte berechnet werden. Dies ermöglicht es Ihnen beispielsweise, die Grenzen des Scroll-Containers so anzupassen, dass das Zielelement als sichtbar angesehen wird, auch wenn seine Pixel noch nicht im Viewport des Containers angezeigt werden, oder das Ziel als teilweise verborgen zu behandeln, wenn eine Kante zu nah an der Kante des Begrenzungsrahmens des Containers liegt.

Beachten Sie, dass, wenn das Wurzelelement ebenfalls ein scrollbarer Container ist, die scrollMargin und rootMargin kombiniert werden, um das effektive Begrenzungsrechteck zu bestimmen, das für die Berechnung der Schnittpunkte mit dem Ziel verwendet wird.

Weitere Informationen finden Sie unter The intersection root and scroll margin in der API-Übersicht.

Wert

Ein String, ähnlich formatiert wie der Wert der CSS margin-Eigenschaft.

Der angegebene Rand definiert Offsets für eine oder mehrere Seiten eines Scroll-Container-Clipping-Rechtecks. Wenn scrollMargin nicht angegeben ist, als das Objekt instanziiert wurde, ist der Standardwert der String "0px 0px 0px 0px".

Beispiel

Karussell mit Scroll-Rand

Dieses Beispiel definiert ein scrollbares Feld (das Wurzelelement), das ein Bildkarussell enthält, welches anfangs nicht sichtbar ist. Ein Beobachter auf dem Wurzelelement beobachtet die Zielelemente der Bilder innerhalb des Karussells. Wenn ein Bildelement beginnt, mit dem Wurzelelement zu schneiden, wird das Bild geladen, der Schnittpunkt wird protokolliert, und der Beobachter wird entfernt.

Das Beispiel ermöglicht es Ihnen, die scrollMargin zu ändern, um zu sehen, wie sich dies ändert, wenn Ziele innerhalb des scrollbaren Karussells zu schneiden beginnen.

HTML

Der untenstehende Code definiert das root-container <div>-Element, das wir als Wurzelelement des Intersection Observers verwenden werden. Dies enthält wiederum ein <p>-Element, das verwendet wird, um die anderen Elemente "standardmäßig" aus der Ansicht zu schieben, ein carousel-<div>, und einen margin-indicator (verwendet, um die Größe des auf scrollbare Elemente innerhalb des Wurzelelements angewandten Randes anzuzeigen).

Die <img>-Elemente innerhalb des Karussells haben ein data-src-Attribut, das einen Dateinamen enthält. In unserem Beobachtercode werden wir dieses Attribut verwenden, um das img.src festzulegen, wenn jedes Bild beginnt, mit dem Wurzelelement zu schneiden, was das Bild lädt.

html
<div id="root-container">
  <p>content before (scroll down to carousel)</p>

  <div class="flex-container">
    <div class="carousel">
      <img
        data-src="ballon-portrait.jpg"
        class="lazy-carousel-img"
        alt="Balloon portrait" />
      <img
        data-src="balloon-small.jpg"
        class="lazy-carousel-img"
        alt="balloon-small" />
      <img data-src="surfer.jpg" class="lazy-carousel-img" alt="surfer" />
      <img
        data-src="border-diamonds.png"
        class="lazy-carousel-img"
        alt="border-diamonds" />
      <img data-src="fire.png" class="lazy-carousel-img" alt="fire" />
      <img data-src="puppy-header.jpg" class="lazy-carousel-img" alt="puppy" />
      <img data-src="moon.jpg" class="lazy-carousel-img" alt="moon" />
      <img data-src="rhino.jpg" class="lazy-carousel-img" alt="rhino" />
    </div>
    <div id="margin-indicator"></div>
  </div>
  <p>content after</p>
</div>
html
<div class="controls">
  <label>
    Set the right margin of the scroll root:
    <input id="margin" type="number" value="0" step="5" />px
  </label>
</div>

CSS

css
#root-container {
  height: 250px;
  overflow-y: auto;
  border: solid blue;
}

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 */
}

.controls {
  margin-top: 10px;
}

JavaScript

Der erste Teil des Codes definiert die Funktion createImageObserver(), die wir verwenden, um IntersectionObserver-Objekte zu erstellen und der Variablen imageObserver zuzuweisen. Wir verwenden eine Funktion, weil Beobachteroptionen nach der Konstruktion nicht geändert werden können, und wir wollen in der Lage sein, die Auswirkungen verschiedener scrollMargin-Werte zu demonstrieren.

Der IntersectionObserver wird ohne rootMargin, mit einem nahezu null threshold und einem scrollMargin erstellt, das seinen Wert vom margin-Eingabewert erhält und der auf alle Seiten des Scroll-Containers angewendet wird.

Der Rückruf wird für alle beobachteten Ziele aufgerufen. Für schneidende Ziele setzt er das img.src auf den Namen des zu ladenden Bildes (aus dem img.dataset.src), protokolliert den Schnittpunkt und hört dann auf, das Bild zu beobachten.

Der Code am Ende der Funktion ruft IntersectionObserver.observe() auf jedem Bild auf, um den Beobachter zu starten.

js
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}px`, // 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
  });
}

Der folgende Code erstellt den Beobachter mit createImageObserver() beim Start und wann immer sich der margin-Eingabewert ändert. Wenn das IntersectionObserver-Interface nicht unterstützt wird, werden alle Bilder sofort geladen.

js
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.",
  );
}

Ergebnisse

Scrollen Sie nach unten, um das Karussell anzuzeigen. Die sichtbaren Bilder sollten sofort geladen werden. Wenn Sie das Karussell nach rechts scrollen, sollten Sie beobachten, dass die Bilder geladen werden, sobald das Element sichtbar wird.

Sie können die bereitgestellte Steuerung verwenden, um den Prozentsatz des Scroll-Randes zu ändern (nachdem Sie das Beispiel zurückgesetzt haben). Wenn Sie einen positiven Wert wie 20px festlegen, wird das Clip-Rechteck des Scroll-Containers um 20px vergrößert, und Sie sollten feststellen, dass Bilder erkannt und geladen werden, bevor sie ins Sichtfeld gelangen. Ähnlich bedeutet ein negativer Wert, dass die Schnittstelle erkannt wird, sobald Bilder bereits sichtbar sind.

Spezifikationen

This feature does not appear to be defined in any specification.

Browser-Kompatibilität