Oliver Schmidt

Reflows und cssText

2011-02-03

Note: This post is from my old blog and thus written in German and potentially obsolete.

Ich hatte vor einiger Zeit mit Hilfe von jQuery einen Produkt-Zoom für einen Online-Shop implementiert. Die mittlerweile weit verbreitete Funktionalität also, welche einem beim Mouseover über ein Produktbild einen in Abhängigkeit von der Position des Cursors bestimmten, vergrößerten Ausschnitt dieses Bildes zeigt. Sowas kann man z.B. mit Hilfe des JQZoom Plugins für jQuery umsetzen (was ich allerdings nicht getan habe, weil es mir etwas zu “aufgebläht” ist).

Anfänglich übergab ich in meinem Code einige berechnete Werte als einzelne CSS-Eigenschaften an jQuerys css-Funktion. Also in etwa so:

$('#image').css({ left: calculatedLeftValue, top: calculatedTopValue });

Aus Performance-Gründen, genauer gesagt um mehrere Reflows zu vermeiden, wollte ich dann vor kurzem dazu übergehen, die Werte nicht mehr einzeln an die Funktion zu übergeben, sondern lieber gesammelt als cssText Eigenschaft.

Zur Definition von cssText zitiere ich mal Luke Smiths (Yahoo) Antwort auf einen Blogpost von Nicole Sullivan zum Thema Reflows und Repaints:

The [cssText] property accepts the string value you would (but shouldn’t) populate the inline style attribute in markup with. With the exception of Opera 9.x, value updates to cssText are immediately normalized to the current string representation of all properties.

cssText bietet also die Möglichkeit einem Element Style-Angaben gebündelt zuzuweisen, anstatt dies einzeln zu tun (document.getElementById('image').style.left = '100px'; etc.) und damit möglicherweise mehrere Reflows hervorzurufen.

In “vanilla” JavaScript sieht das dann z.B. so aus:

document.getElementById('image').style.cssText +=
  '; left:' + left + 'px; top:' + top + 'px;';

Da cssText die Inhalte eines möglicherweise vorhandenen Style-Attributs überschreibt, kann man – wie auch oben zu sehen – ggf. mit += arbeiten, um die neuen Eigenschaften den bereits vorhandenen hinzuzufügen.

Der Ansatz unter Verwendung von jQuery:

$('#image').css(
  'cssText',
  'left:' + calculatedLeftValue + 'px; top:' + calculatedTopValue + 'px;'
);

Um auch in jQuery bereits vorhandene Style-Angaben mit neuen zu erweitern, kann man z.B. so vorgehen:

var $image = $('#image');
$image.css(
  'cssText',
  $image.attr('style') +
    ';top:' +
    calculatedTopValue +
    'px;left:' +
    calculatedLeftValue +
    'px;'
);