Signatur
Beschreibung
Die Eigenschaft values der Schnittstelle CSSMathProduct aus dem CSS Typed Object Model gibt ein CSSNumericArray zurück. Es enthält die Operanden, die miteinander multipliziert werden. Ein CSSMathProduct ist die objektorientierte Form eines Ausdrucks wie calc(10px * 2).
Wofür braucht man das? Man kann einen Rechenausdruck in seine Bestandteile zerlegen, zum Beispiel um ihn zu analysieren, umzuschreiben oder für Debug-Zwecke darzustellen. Jeder Eintrag ist selbst ein CSSNumericValue. Das kann ein einfacher CSSUnitValue sein (etwa 10px), aber auch ein verschachtelter Ausdruck wie CSSMathSum oder CSSMathInvert. Eine Division wird intern nämlich als Multiplikation mit dem Kehrwert (CSSMathInvert) dargestellt.
Das zurückgegebene CSSNumericArray ist iterierbar: Es hat eine length-Eigenschaft, einen Indexzugriff (values[0]) und funktioniert mit for...of. Es ist aber kein echtes Array, deshalb fehlen Methoden wie map(). Die Liste ist nur lesbar. Neue Operanden fügt man nicht direkt ein, sondern erzeugt einen neuen Ausdruck, z. B. mit new CSSMathProduct(...) oder CSSNumericValue.prototype.mul().
Rückgabewert
CSSNumericValue-Objekten. Das sind die Faktoren des Produkts in der Reihenfolge, in der sie übergeben wurden.Beispiele
Operanden eines Produkts auslesen
// Produkt aus 10px und 2 erzeugen (entspricht calc(10px * 2))
const product = new CSSMathProduct(CSS.px(10), CSS.number(2));
console.log(product.values.length);
console.log(product.values[0].toString());
console.log(product.values[1].toString());
console.log(product.toString());
Über alle Faktoren iterieren
const product = new CSSMathProduct(
CSS.px(100),
CSS.number(1.5),
new CSSMathInvert(CSS.number(4)) // entspricht "/ 4"
);
for (const factor of product.values) {
// Ein CSSUnitValue hat value und unit, verschachtelte Ausdrücke haben operator
if (factor instanceof CSSUnitValue) {
console.log(`Einheitswert: ${factor.value} (${factor.unit})`);
} else {
console.log(`Ausdruck: ${factor.operator} -> ${factor.toString()}`);
}
}
Produkt rekursiv in lesbaren Text umwandeln
const describe = (value) => {
if (value instanceof CSSUnitValue) return `${value.value}${value.unit === 'number' ? '' : value.unit}`;
if (value instanceof CSSMathProduct) {
// CSSNumericArray ist kein Array, deshalb vorher Array.from()
return Array.from(value.values, describe).join(' × ');
}
if (value instanceof CSSMathInvert) return `1/(${describe(value.value)})`;
return value.toString();
};
const width = new CSSMathProduct(CSS.vw(50), new CSSMathInvert(CSS.number(3)));
console.log(describe(width));
// Wichtig · Fallstricke
- Browser-Unterstützung: Das CSS Typed OM gibt es in Chromium-Browsern (Chrome, Edge, Opera) ab Version 66 und in Safari ab 16.4. Firefox unterstützt es derzeit nicht. Vorher prüfen, z. B. mit
if ('CSSMathProduct' in window). - Kein echtes Array:
CSSNumericArrayhat keinmap(),filter()usw. Bei Bedarf zuerst mitArray.from(product.values)oder[...product.values]umwandeln. - Schreibgeschützt: Eine Zuweisung an
valueswird ignoriert (im Strict Mode gibt es einenTypeError). Wer andere Operanden braucht, erzeugt einen neuenCSSMathProduct. - Vereinfachung:
CSSNumericValue.prototype.mul()liefert nicht immer einenCSSMathProduct. Lässt sich das Ergebnis direkt ausrechnen (z. B.CSS.px(10).mul(2)), kommt einCSSUnitValuewie20pxzurück, und der hat keinevalues-Eigenschaft. Auch Werte auscomputedStyleMap()sind meist schon ausgerechnet. Deshalb immer mitinstanceof CSSMathProductprüfen. - Divisionen tauchen in
valuesalsCSSMathInvert-Objekte auf, nicht als eigener Operator.