Signatur
Beschreibung
Highlight gehört zur CSS Custom Highlight API und verhält sich wie ein Set aus Range- bzw. StaticRange-Objekten. Deshalb arbeitet forEach() genauso wie Set.prototype.forEach(): Der Callback läuft für jeden Bereich einmal, in der Reihenfolge, in der die Bereiche hinzugefügt wurden.
Die Methode eignet sich, um alle Bereiche eines Highlights auszuwerten oder zu prüfen – zum Beispiel, um den markierten Text auszulesen, Treffer einer Suche zu zählen oder vor dem Entfernen zu protokollieren, welche Bereiche noch hervorgehoben sind.
Wie bei Set bekommt der Callback den Wert zweimal übergeben (als value und als key). Das hält die Schnittstelle einheitlich mit Map.prototype.forEach(). Wenn du Ergebnisse zurückgeben oder die Schleife vorzeitig abbrechen willst, nimm lieber for...of oder Array.from(highlight).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callbackFn Pflicht | (value: AbstractRange, key: AbstractRange, highlight: Highlight) => void | Funktion, die für jeden Bereich aufgerufen wird. Sie erhält value (den aktuellen Bereich), key (denselben Bereich noch einmal, wie bei Set) und highlight (das Highlight, auf dem forEach() aufgerufen wurde). |
|
| $thisArg | any | undefined | Wert, der beim Ausführen von callbackFn als this gilt. Bei Pfeilfunktionen hat er keine Wirkung. |
Rückgabewert
forEach() lässt sich nicht verketten.Beispiele
Highlight anlegen und alle Bereiche ausgeben
// HTML: <p id="text">JavaScript ist vielseitig und JavaScript ist schnell.</p>
const textNode = document.getElementById('text').firstChild;
const r1 = new Range();
r1.setStart(textNode, 0);
r1.setEnd(textNode, 10);
const r2 = new Range();
r2.setStart(textNode, 27);
r2.setEnd(textNode, 37);
const highlight = new Highlight(r1, r2);
CSS.highlights.set('treffer', highlight);
highlight.forEach((range, key, set) => {
console.log(`"${range.toString()}"`, range === key, set === highlight);
});
Suchtreffer hervorheben und mit forEach auswerten
// CSS: ::highlight(suche) { background: yellow; }
const markiereBegriff = (root, begriff) => {
const highlight = new Highlight();
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
let node;
while ((node = walker.nextNode())) {
const text = node.textContent.toLowerCase();
let idx = text.indexOf(begriff.toLowerCase());
while (idx !== -1) {
const range = new Range();
range.setStart(node, idx);
range.setEnd(node, idx + begriff.length);
highlight.add(range);
idx = text.indexOf(begriff.toLowerCase(), idx + begriff.length);
}
}
CSS.highlights.set('suche', highlight);
return highlight;
};
const hl = markiereBegriff(document.body, 'api');
let nr = 0;
hl.forEach((range) => {
nr += 1;
console.log(`Treffer ${nr} in <${range.startContainer.parentElement.tagName.toLowerCase()}>`);
});
console.log(`Gesamt: ${hl.size}`);
thisArg nutzen, um Ergebnisse zu sammeln
const highlight = new Highlight();
const p = document.createElement('p');
p.textContent = 'Hallo Welt';
document.body.append(p);
const r = new Range();
r.selectNodeContents(p);
highlight.add(r);
const sammler = { texte: [] };
highlight.forEach(function (range) {
this.texte.push(range.toString());
}, sammler);
console.log(sammler.texte);
// Wichtig · Fallstricke
- Kein Abbruch möglich:
returnim Callback springt nur zum nächsten Bereich weiter. Um vorzeitig abzubrechen, nimmfor (const range of highlight)mitbreak. - Ändern während der Schleife: Das Verhalten entspricht dem von
Set. Bereiche, die während des Durchlaufs mitadd()hinzukommen, werden noch besucht. Bereiche, die vor ihrem Aufruf mitdelete()entfernt werden, werden übersprungen. - Bereiche ändern sich mit dem DOM: Ein normaler
Rangepasst sich an, wenn sich das DOM ändert. EinStaticRangetut das nicht und kann danach auf ungültige Stellen zeigen. Prüfe deshalb im Callback, ob ein Bereich noch gültig ist, zum Beispiel mitrange.collapsed. - Browser-Unterstützung: Die CSS Custom Highlight API gibt es in Chromium ab Version 105 und in Safari ab 17.2. In Firefox ist sie erst in neueren Versionen verfügbar. Frage die Unterstützung vorher ab, etwa mit
if ('highlights' in CSS). - Ein
Highlightwird erst sichtbar, wenn es mitCSS.highlights.set()registriert und über::highlight(name)gestaltet wurde. FürforEach()selbst ist die Registrierung nicht nötig.