Start · Sprachen · JavaScript · Referenz · Element: contentvisibilityautostatechange

Element: contentvisibilityautostatechange

Ereignis

Wird auf einem Element mit <code>content-visibility: auto</code> ausgelöst, wenn der Browser das Rendern seiner Inhalte beginnt oder wieder aufnimmt.

seit JavaScript Baseline 2024: Chrome/Edge 108+, Firefox 130+, Saf Kategorie: webapi

Signatur

element.addEventListener("contentvisibilityautostatechange", handler)

Beschreibung

Mit der CSS-Eigenschaft content-visibility: auto darf der Browser Layout und Zeichnen der Inhalte eines Elements überspringen, solange das Element für den Nutzer nicht relevant ist, also z. B. außerhalb des Viewports liegt und weder Fokus noch Textauswahl enthält. Das Ereignis contentvisibilityautostatechange meldet genau diesen Zustandswechsel: Es wird ausgelöst, wenn der Browser die Inhalte ab jetzt überspringt, und auch dann, wenn er sie wieder rendert.

Der Handler bekommt ein ContentVisibilityAutoStateChangeEvent. Dessen boolesche Eigenschaft skipped sagt dir, ob die Inhalte gerade übersprungen werden (true) oder wieder gerendert werden (false).

Typische Einsatzfälle:

  • Arbeit pausieren, die niemand sieht: Canvas- oder WebGL-Animationen, Video-Vorschauen, Polling oder Timer.
  • Inhalte nachladen oder aufbauen, sobald ein Abschnitt relevant wird, zum Beispiel Daten per fetch() holen oder Diagramme zeichnen.
  • Ressourcen freigeben, wenn lange Listen oder Feeds aus dem sichtbaren Bereich gescrollt werden.

Du registrierst das Ereignis mit addEventListener("contentvisibilityautostatechange", …) oder, wo der Browser es unterstützt, über die Eigenschaft element.oncontentvisibilityautostatechange. Es lässt sich nicht abbrechen, und seine Standardaktion kann man nicht verhindern.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, immer "contentvisibilityautostatechange".
$handler Pflicht (event: ContentVisibilityAutoStateChangeEvent) => void Callback, der bei jedem Zustandswechsel aufgerufen wird. event.skipped ist true, wenn die Inhalte übersprungen werden, und false, wenn sie wieder gerendert werden.
$options boolean | AddEventListenerOptions false Übliche Listener-Optionen wie once, signal (zum Entfernen per AbortController) oder capture.

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt nichts zurück. Der Handler erhält ein ContentVisibilityAutoStateChangeEvent mit der schreibgeschützten Eigenschaft skipped: boolean.

Beispiele

Canvas-Animation pausieren, solange der Abschnitt übersprungen wird

// CSS: .chart-section { content-visibility: auto; contain-intrinsic-size: auto 400px; }
const section = document.querySelector('.chart-section');
const canvas = section.querySelector('canvas');
const ctx = canvas.getContext('2d');
let frameId = null;
let angle = 0;

const draw = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(100 + Math.cos(angle) * 50, 100 + Math.sin(angle) * 50, 10, 10);
  angle += 0.05;
  frameId = requestAnimationFrame(draw);
};

section.addEventListener('contentvisibilityautostatechange', (event) => {
  if (event.skipped) {
    cancelAnimationFrame(frameId);
    frameId = null;
    console.log('Animation pausiert');
  } else if (frameId === null) {
    frameId = requestAnimationFrame(draw);
    console.log('Animation läuft');
  }
});
Animation läuft Animation pausiert // nach dem Wegscrollen

Daten erst laden, wenn ein Abschnitt relevant wird

const sections = document.querySelectorAll('article.lazy');

const loadContent = async (event) => {
  if (event.skipped) return;
  const article = event.target;
  // Listener entfernen, damit nur einmal geladen wird
  article.removeEventListener('contentvisibilityautostatechange', loadContent);
  const response = await fetch(`/api/artikel/${article.dataset.id}`);
  const { html } = await response.json();
  article.querySelector('.body').textContent = html;
  console.log(`Artikel ${article.dataset.id} geladen`);
};

sections.forEach((article) => {
  article.style.contentVisibility = 'auto';
  article.style.containIntrinsicSize = 'auto 600px';
  article.addEventListener('contentvisibilityautostatechange', loadContent);
});
Artikel 42 geladen

on-Property und Entfernen per AbortController

const panel = document.querySelector('#feed');
const controller = new AbortController();

panel.addEventListener(
  'contentvisibilityautostatechange',
  ({ skipped }) => console.log(skipped ? 'übersprungen' : 'gerendert'),
  { signal: controller.signal }
);

// Alternativ, sofern der Browser die Eigenschaft kennt:
if ('oncontentvisibilityautostatechange' in panel) {
  panel.oncontentvisibilityautostatechange = (e) => console.log('skipped =', e.skipped);
}

// Später: Listener abmelden
controller.abort();
panel.oncontentvisibilityautostatechange = null;
gerendert skipped = false

// Wichtig · Fallstricke

  • Nur bei content-visibility: auto: Bei visible oder hidden wird das Ereignis nicht ausgelöst. Wenn du den Wert dynamisch änderst, bekommst du die Ereignisse nur, solange auto aktiv ist.
  • Relevanz ist mehr als Sichtbarkeit: Ein Element bleibt auch außerhalb des Viewports relevant, wenn es Fokus oder eine Textauswahl enthält oder in der Top-Layer liegt. Dann ist skipped weiterhin false. Wenn du nur wissen willst, ob ein Element sichtbar ist, nimm besser einen IntersectionObserver.
  • Asynchron: Der Browser löst das Ereignis im Rendering-Zyklus aus, also nicht synchron beim Scrollen. Direkt nach dem Laden der Seite kann es für den Anfangszustand einmal feuern. Verlass dich darauf aber nicht, sondern prüf den Zustand im Code selbst.
  • contain-intrinsic-size setzen: Ohne eine geschätzte Größe fallen übersprungene Elemente auf die Höhe 0 zusammen. Das lässt die Scrollleiste springen und führt zu vielen Zustandswechseln.
  • Listener direkt am Element registrieren: Verlass dich bei diesem Ereignis nicht auf Event-Delegation über einen Vorfahren.
  • Browser-Kompatibilität: Unterstützt in Chromium ab Version 108, Firefox ab etwa 130 und Safari ab 18. Bei älteren Browsern prüfst du die Unterstützung vorher, z. B. mit CSS.supports('content-visibility', 'auto') und 'ContentVisibilityAutoStateChangeEvent' in window, und sorgst dafür, dass die Seite ohne das Ereignis weiter funktioniert (etwa mit einem IntersectionObserver). Die Eigenschaft oncontentvisibilityautostatechange gibt es nicht überall. addEventListener ist der sichere Weg.