cssHooks in jQuery

In jQuery Version 1.4.3 wurde ein neues Objekt eingeführt, welches die Definition eigener Getter und Setter für CSS-Eigenschaften ermöglicht. So lassen sich beispielsweise vereinfachte Getter/Setter erstellen, welche Box-Schatten, Gradienten oder auch runde Ecken (border-radius, -moz-border-radius, -webkit-border-radius) für verschiedene Browser handhaben.

The $.cssHooks object provides a way to define functions for getting and setting particular CSS values. It can also be used to create new cssHooks for normalizing CSS3 features such as box shadows and gradients.

Details zu Eigenschaften und Verwendung dieses Objekts sind unter
http://api.jquery.com/jQuery.cssHooks/ zu finden.
Eine weitere Beschreibung zum Erstellen von cssHooks gibt es unter
http://www.webmuse.co.uk/blog/csshooks-in-jquery/.

Einsatzgebiete

Auf api.jquery.com wird als Beispiel einer möglichen Verwendung die Definition runder Ecken (border-radius) angegeben. Bei der Arbeit mit jQuery reicht dann völlig aus, nur auf border-radius zuzugreifen. Intern werden über den beschrieben cssHook nur die jeweils benötigte Browservariante (border-radius, -moz-border-radius, -webkit-border-radius) angesprochen (siehe Quelltext, „Defining a complete cssHook“).

cssHook: background-position

Bei der Arbeit mit jQuery und hierbei nach der Umstellung auf eine Version neuer 1.4.3, fiel auf, dass sich einige Code-Teile nicht mehr so wie vorher verhielten. Speziell bei Block-Elemente, welche mit einer Hintergrundgrafik ausgestattet waren und diese mit animate() bewegt wurde, war nach der Umstellung von der Animation nichts mehr zu sehen. Fehler-/Warnmeldungen wurden dabei auch nicht ausgegeben.

Grund für diese Probleme mit animate() war die Verwendung der CSS-Eigenschaft background-position. Bei jQuery-Versionen nach 1.4.3 musste die Zuweisung von Hintergrundkoordinaten nicht wie bisher definiert werden:

$('...').animate({'backgroundPosition':'2px 2px'});

Sondern durch Angabe jeder einzelnen Koordinate mit:

$('...').animate({'backgroundPositionX':'2px', 'backgroundPositionY':'2px'});

Verwendet man dennoch backgroundPosition, dann kann auch hier nur noch ein Positionsparameter übergeben werden, welcher sich dann allerdings nur auf die x-Position auswirkt.

Zurück zu den eigentlichen cssHooks … aus dieser Umstellung ergab sich nun folgendes Problem: backgroundPositionX (und auch y) funktionierte zudem nicht bei Browsern wie FireFox oder Opera. Auch hier sah man von der Animation nichts.

Die Lösung war das einfügen eines cssHooks, welcher die Verwendung von backgroundPositionX und backgroundPositionY in allen Browser ermöglicht. Auf github fand sich bereits eine Variante, die genau dieses Problem berücksichtigt. Dazu ist der nachfolgende JS-Code erforderlich, welcher das bestehende jQuery um diese Funktion erweitert.

jquery-cssHooks / bgpos.js:

/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
 * Licensed under the MIT License (LICENSE.txt).
 */
(function($) {
    // backgroundPosition[X,Y] get hooks
    var $div = $('
'); $.support.backgroundPosition = $div.css('backgroundPosition') === "3px 5px" ? true : false; $.support.backgroundPositionXY = $div.css('backgroundPositionX') === "3px" ? true : false; $div = null; var xy = ["X","Y"]; // helper function to parse out the X and Y values from backgroundPosition function parseBgPos(bgPos) { var parts = bgPos.split(/\s/), values = { "X": parts[0], "Y": parts[1] }; return values; } if (!$.support.backgroundPosition && $.support.backgroundPositionXY) { $.cssHooks.backgroundPosition = { get: function( elem, computed, extra ) { return $.map(xy, function( l, i ) { return $.css(elem, "backgroundPosition" + l); }).join(" "); }, set: function( elem, value ) { $.each(xy, function( i, l ) { var values = parseBgPos(value); elem.style[ "backgroundPosition" + l ] = values[ l ]; }); } }; } if ($.support.backgroundPosition && !$.support.backgroundPositionXY) { $.each(xy, function( i, l ) { $.cssHooks[ "backgroundPosition" + l ] = { get: function( elem, computed, extra ) { var values = parseBgPos( $.css(elem, "backgroundPosition") ); return values[ l ]; }, set: function( elem, value ) { var values = parseBgPos( $.css(elem, "backgroundPosition") ), isX = l === "X"; elem.style.backgroundPosition = (isX ? value : values[ "X" ]) + " " + (isX ? values[ "Y" ] : value); } }; $.fx.step[ "backgroundPosition" + l ] = function( fx ) { $.cssHooks[ "backgroundPosition" + l ].set( fx.elem, fx.now + fx.unit ); }; }); } })(jQuery);

Quelle: https://github.com/brandonaaron/jquery-cssHooks/blob/master/bgpos.js

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.