jQuery animer backgroundColor


327

J'essaie d'animer un changement de backgroundColor en utilisant jQuery au survol de la souris.

J'ai vérifié un exemple et je semble avoir raison, cela fonctionne avec d'autres propriétés comme fontSize, mais avec backgroundColor j'obtiens et l'erreur js "Propriété non valide". L'élément avec lequel je travaille est un div.

$(".usercontent").mouseover(function() {
    $(this).animate({ backgroundColor: "olive" }, "slow");
});

Des idées?


Pour jquery 1.4.2 avec effet jquery 1.8, je dois admettre que la solution Andrew fonctionne parfaitement. Voir son article ci-dessous.
Patrick Desjardins

1
Remarque: ce plugin détecte la couleur d'arrière-plan actuelle de l'élément - le navigateur Chrome renvoie rgba(0, 0, 0, 0)au lieu de la valeur vide / nulle attendue lorsqu'aucune couleur d'arrière-plan n'est définie. Pour "corriger" cela, l'élément doit avoir une couleur d'arrière-plan initiale.
Shadow Wizard est Ear For You

La page liée semble cassée (au moins la page du projet et la page de démonstration).
Paolo Stefan

Réponses:


333

Le plugin couleur n'est que de 4 Ko, donc beaucoup moins cher que la bibliothèque d'interface utilisateur. Bien sûr, vous voudrez utiliser une version décente du plugin et non une vieille chose buggy qui ne gère pas Safari et se bloque lorsque les transitions sont trop rapides. Puisqu'une version minifiée n'est pas fournie, vous pouvez tester différents compresseurs et créer votre propre version min. YUI obtient la meilleure compression dans ce cas, ne nécessitant que 2317 octets et comme il est si petit - le voici:

(function (d) {
    d.each(["backgroundColor", "borderBottomColor", "borderLeftColor", "borderRightColor", "borderTopColor", "color", "outlineColor"], function (f, e) {
        d.fx.step[e] = function (g) {
            if (!g.colorInit) {
                g.start = c(g.elem, e);
                g.end = b(g.end);
                g.colorInit = true
            }
            g.elem.style[e] = "rgb(" + [Math.max(Math.min(parseInt((g.pos * (g.end[0] - g.start[0])) + g.start[0]), 255), 0), Math.max(Math.min(parseInt((g.pos * (g.end[1] - g.start[1])) + g.start[1]), 255), 0), Math.max(Math.min(parseInt((g.pos * (g.end[2] - g.start[2])) + g.start[2]), 255), 0)].join(",") + ")"
        }
    });

    function b(f) {
        var e;
        if (f && f.constructor == Array && f.length == 3) {
            return f
        }
        if (e = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(f)) {
            return [parseInt(e[1]), parseInt(e[2]), parseInt(e[3])]
        }
        if (e = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(f)) {
            return [parseFloat(e[1]) * 2.55, parseFloat(e[2]) * 2.55, parseFloat(e[3]) * 2.55]
        }
        if (e = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(f)) {
            return [parseInt(e[1], 16), parseInt(e[2], 16), parseInt(e[3], 16)]
        }
        if (e = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(f)) {
            return [parseInt(e[1] + e[1], 16), parseInt(e[2] + e[2], 16), parseInt(e[3] + e[3], 16)]
        }
        if (e = /rgba\(0, 0, 0, 0\)/.exec(f)) {
            return a.transparent
        }
        return a[d.trim(f).toLowerCase()]
    }
    function c(g, e) {
        var f;
        do {
            f = d.css(g, e);
            if (f != "" && f != "transparent" || d.nodeName(g, "body")) {
                break
            }
            e = "backgroundColor"
        } while (g = g.parentNode);
        return b(f)
    }
    var a = {
        aqua: [0, 255, 255],
        azure: [240, 255, 255],
        beige: [245, 245, 220],
        black: [0, 0, 0],
        blue: [0, 0, 255],
        brown: [165, 42, 42],
        cyan: [0, 255, 255],
        darkblue: [0, 0, 139],
        darkcyan: [0, 139, 139],
        darkgrey: [169, 169, 169],
        darkgreen: [0, 100, 0],
        darkkhaki: [189, 183, 107],
        darkmagenta: [139, 0, 139],
        darkolivegreen: [85, 107, 47],
        darkorange: [255, 140, 0],
        darkorchid: [153, 50, 204],
        darkred: [139, 0, 0],
        darksalmon: [233, 150, 122],
        darkviolet: [148, 0, 211],
        fuchsia: [255, 0, 255],
        gold: [255, 215, 0],
        green: [0, 128, 0],
        indigo: [75, 0, 130],
        khaki: [240, 230, 140],
        lightblue: [173, 216, 230],
        lightcyan: [224, 255, 255],
        lightgreen: [144, 238, 144],
        lightgrey: [211, 211, 211],
        lightpink: [255, 182, 193],
        lightyellow: [255, 255, 224],
        lime: [0, 255, 0],
        magenta: [255, 0, 255],
        maroon: [128, 0, 0],
        navy: [0, 0, 128],
        olive: [128, 128, 0],
        orange: [255, 165, 0],
        pink: [255, 192, 203],
        purple: [128, 0, 128],
        violet: [128, 0, 128],
        red: [255, 0, 0],
        silver: [192, 192, 192],
        white: [255, 255, 255],
        yellow: [255, 255, 0],
        transparent: [255, 255, 255]
    }
})(jQuery);

2
D'accord, allez sur le lien proposé par Andrew. Téléchargez le fichier. Vous devez l'ajouter à votre projet. Vous pouvez toujours avoir jquery.effects.core dans votre projet, cela fonctionnera parfaitement. Merci pour la réponse. +1
Patrick Desjardins

3
J'ai simplement collé ce qui précède dans mon fichier 'jquery-ui-1.8.2.min.js' existant et ... tout fonctionnait toujours :-)
Dave Everitt

7
Je voudrais noter que l'année dernière (2011), l'auteur de ce plugin a publié une version 2 qui contient de nombreuses fonctionnalités intéressantes, mais qui n'est pas requise pour les fonctionnalités de base pour lesquelles cette bibliothèque est généralement recherchée. Il fait maintenant plus de 20 Ko. Vous pouvez sélectionner la v1branche pour obtenir l'ancienne version (qui fonctionne toujours) mais est beaucoup plus légère.
Aren

6
FWIW - vous pouvez supprimer les mappages couleur à RVB dans le code et réduire davantage la taille: raw.github.com/gist/1891361/… . L'inconvénient est que vous ne pouvez pas utiliser de noms de couleurs pour l'animation. Vous devrez utiliser des valeurs RVB.
Niyaz

4
jQuery 1.8 casse cette prise en btw. curCSS n'est plus dans jQuery.
Rich Bradshaw

68

J'ai eu le même problème et l'ai résolu en incluant l'interface utilisateur jQuery. Voici le script complet:

<!-- include Google's AJAX API loader -->
<script src="http://www.google.com/jsapi"></script>
<!-- load JQuery and UI from Google (need to use UI to animate colors) -->
<script type="text/javascript">
google.load("jqueryui", "1.5.2");
</script>


<script type="text/javascript">
$(document).ready(function() {
$('#menu ul li.item').hover(
    function() {
        $(this).stop().animate({backgroundColor:'#4E1402'}, 300);
        }, function () {
        $(this).stop().animate({backgroundColor:'#943D20'}, 100);
    });
});
</script>

61

Faites-le avec CSS3-Transitions. Le support est excellent (tous les navigateurs modernes, même IE). Avec Compass et SASS, cela se fait rapidement:

#foo {background:red; @include transition(background 1s)}
#foo:hover {background:yellow}

CSS pur:

#foo {
background:red;
-webkit-transition:background 1s;
-moz-transition:background 1s;
-o-transition:background 1s;
transition:background 1s
}
#foo:hover {background:yellow}

J'ai écrit un article allemand sur ce sujet: http://www.solife.cc/blog/animation-farben-css3-transition.html


6
Jouez avec les transitions de vol stationnaire et de clic sur: jsfiddle.net/K5Qyx
Dem Pilafian


13

Vous pouvez utiliser jQuery UI pour ajouter cette fonctionnalité. Vous pouvez saisir exactement ce dont vous avez besoin, donc si vous souhaitez animer la couleur, tout ce que vous avez à inclure est le code suivant. J'ai obtenu si de la dernière interface utilisateur jQuery (actuellement 1.8.14)

/******************************************************************************/
/****************************** COLOR ANIMATIONS ******************************/
/******************************************************************************/

// override the animation for color styles
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
    'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
function(i, attr) {
    $.fx.step[attr] = function(fx) {
        if (!fx.colorInit) {
            fx.start = getColor(fx.elem, attr);
            fx.end = getRGB(fx.end);
            fx.colorInit = true;
        }

        fx.elem.style[attr] = 'rgb(' +
            Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
            Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
            Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
    };
});

// Color Conversion functions from highlightFade
// By Blair Mitchelmore
// http://jquery.offput.ca/highlightFade/

// Parse strings looking for color tuples [255,255,255]
function getRGB(color) {
        var result;

        // Check if we're already dealing with an array of colors
        if ( color && color.constructor == Array && color.length == 3 )
                return color;

        // Look for rgb(num,num,num)
        if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
                return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];

        // Look for rgb(num%,num%,num%)
        if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
                return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

        // Look for #a0b1c2
        if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
                return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

        // Look for #fff
        if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
                return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

        // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
        if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
                return colors['transparent'];

        // Otherwise, we're most likely dealing with a named color
        return colors[$.trim(color).toLowerCase()];
}

function getColor(elem, attr) {
        var color;

        do {
                color = $.curCSS(elem, attr);

                // Keep going until we find an element that has color, or we hit the body
                if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
                        break;

                attr = "backgroundColor";
        } while ( elem = elem.parentNode );

        return getRGB(color);
};

Il ne fait que 1,43 Ko après compression avec YUI:

$.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,a){$.fx.step[a]=function(c){if(!c.colorInit){c.start=getColor(c.elem,a);c.end=getRGB(c.end);c.colorInit=true}c.elem.style[a]="rgb("+Math.max(Math.min(parseInt((c.pos*(c.end[0]-c.start[0]))+c.start[0],10),255),0)+","+Math.max(Math.min(parseInt((c.pos*(c.end[1]-c.start[1]))+c.start[1],10),255),0)+","+Math.max(Math.min(parseInt((c.pos*(c.end[2]-c.start[2]))+c.start[2],10),255),0)+")"}});function getRGB(b){var a;if(b&&b.constructor==Array&&b.length==3){return b}if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b)){return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)]}if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b)){return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55]}if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b)){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b)){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}if(a=/rgba\(0, 0, 0, 0\)/.exec(b)){return colors.transparent}return colors[$.trim(b).toLowerCase()]}function getColor(c,a){var b;do{b=$.curCSS(c,a);if(b!=""&&b!="transparent"||$.nodeName(c,"body")){break}a="backgroundColor"}while(c=c.parentNode);return getRGB(b)};

Vous pouvez également animer des couleurs à l'aide de transitions CSS3, mais il n'est pris en charge que par les navigateurs modernes.

a.test {
  color: red;
  -moz-transition-property: color;  /* FF4+ */
  -moz-transition-duration: 1s;
  -webkit-transition-property: color;  /* Saf3.2+, Chrome */
  -webkit-transition-duration: 1s;
  -o-transition-property: color;  /* Opera 10.5+ */
  -o-transition-duration: 1s;
  -ms-transition-property: color;  /* IE10? */
  -ms-transition-duration: 1s;
  transition-property: color;  /* Standard */
  transition-duration: 1s;
  }

  a.test:hover {
  color: blue;
  }

Utilisation de la propriété raccourcie:

/* shorthand notation for transition properties */
/* transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay]; */

a.test {
  color: red;
  -moz-transition: color 1s;
  -webkit-transition: color 1s;
  -o-transition: color 1s;
  -ms-transition: color 1s;
  transition: color 1s;
  }

a.test {
  color: blue;
 }

Contrairement aux transitions JavaScript standard, les transitions CSS3 sont accélérées matériellement et donc plus fluides. Vous pouvez utiliser Modernizr, pour savoir si le navigateur prend en charge les transitions CSS3, sinon, vous pouvez utiliser jQuery comme solution de rechange:

if ( !cssTransitions() ) {
    $(document).ready(function(){
        $(".test").hover(function () {
                $(this).stop().animate({ backgroundColor: "red" },500)
             }, function() {
                 $(this).stop().animate({ backgroundColor: "blue" },500)}    
             );
    }); 
}

N'oubliez pas d'utiliser stop () pour arrêter l'animation en cours avant d'en démarrer une nouvelle, sinon lorsque vous passez trop rapidement sur l'élément, l'effet continue de clignoter pendant un certain temps.


11

Pour tous ceux qui trouvent cela. Il vaut mieux utiliser la version jQuery UI car elle fonctionne sur tous les navigateurs. Le plugin couleur a des problèmes avec Safari et Chrome. Cela ne fonctionne que parfois.


6
-1 La dernière version du plugin couleur fonctionne parfaitement dans Chrome.
Andrew

3
Il est lourd d'inclure un script supplémentaire pour simplement animer l'arrière
oneiros

11

Vous pouvez utiliser 2 divs:

Vous pouvez mettre un clone dessus et fondre l'original tout en fondant le clone.

Une fois les fondus terminés, restaurez l'original avec le nouveau bg.

$(function(){
    var $mytd = $('#mytd'), $elie = $mytd.clone(), os = $mytd.offset();

      // Create clone w other bg and position it on original
    $elie.toggleClass("class1, class2").appendTo("body")
         .offset({top: os.top, left: os.left}).hide();

    $mytd.mouseover(function() {            
          // Fade original
        $mytd.fadeOut(3000, function() {
            $mytd.toggleClass("class1, class2").show();
            $elie.toggleClass("class1, class2").hide();            
        });
          // Show clone at same time
        $elie.fadeIn(3000);
    });
});​

Exemple jsFiddle


.toggleClass()
.offset()
.fadeIn()
.fadeOut()


peut-être que cela a fonctionné à un moment donné, du moins à droite, il ne semble pas faire ce qu'on attend de lui.
epeleg

@epeleg - Fonctionne dans mac chrome pour moi. Vous cliquez sur le rectangle coloré, et il change de couleur (
2013-07-15

Je ne sais pas comment mais en effet maintenant cela fonctionne sur mon chrome windows7. peut-être lié à la mise à jour de chrome que j'ai faite hier?! de toute façon, comme je l'ai dit, cela fonctionne maintenant.
epeleg

8

J'ai utilisé une combinaison de transitions CSS avec JQuery pour l'effet souhaité; Évidemment, les navigateurs qui ne prennent pas en charge les transitions CSS ne s'animeront pas, mais c'est une option légère qui fonctionne bien pour la plupart des navigateurs et pour mes besoins est une dégradation acceptable.

Jquery pour changer la couleur de fond:

   $('.mylinkholder a').hover(
        function () {
            $(this).css({ backgroundColor: '#f0f0f0' }); 
        },
        function () {
            $(this).css({ backgroundColor: '#fff' });
        }
    );

CSS utilisant la transition pour atténuer le changement de couleur d'arrière-plan

   .mylinkholder a
   {
   transition: background-color .5s ease-in-out;
   -moz-transition: background-color .5s ease-in-out;
   -webkit-transition: background-color .5s ease-in-out; 
  -o-transition: background-color .5s ease-in-out; 
   }

6

De nos jours, le plug-in de couleur jQuery prend en charge les couleurs nommées suivantes:

aqua:[0,255,255],
azure:[240,255,255],
beige:[245,245,220],
black:[0,0,0],
blue:[0,0,255],
brown:[165,42,42],
cyan:[0,255,255],
darkblue:[0,0,139],
darkcyan:[0,139,139],
darkgrey:[169,169,169],
darkgreen:[0,100,0],
darkkhaki:[189,183,107],
darkmagenta:[139,0,139],
darkolivegreen:[85,107,47],
darkorange:[255,140,0],
darkorchid:[153,50,204],
darkred:[139,0,0],
darksalmon:[233,150,122],
darkviolet:[148,0,211],
fuchsia:[255,0,255],
gold:[255,215,0],
green:[0,128,0],
indigo:[75,0,130],
khaki:[240,230,140],
lightblue:[173,216,230],
lightcyan:[224,255,255],
lightgreen:[144,238,144],
lightgrey:[211,211,211],
lightpink:[255,182,193],
lightyellow:[255,255,224],
lime:[0,255,0],
magenta:[255,0,255],
maroon:[128,0,0],
navy:[0,0,128],
olive:[128,128,0],
orange:[255,165,0],
pink:[255,192,203],
purple:[128,0,128],
violet:[128,0,128],
red:[255,0,0],
silver:[192,192,192],
white:[255,255,255],
yellow:[255,255,0]

1
Pourriez-vous s'il vous plaît citer la source. Merci pour la liste btw.
Shrikant Sharat

Cette liste provient du plugin jQuery color: plugins.jquery.com/project/color
spoulson

2
-1 Votre liste de couleurs fait référence à une version obsolète. La version actuelle a au moins une couleur supplémentaire que j'ai remarquée.
Andrew

5

J'aime utiliser delay () pour y arriver, voici un exemple:

jQuery(element).animate({ backgroundColor: "#FCFCD8" },1).delay(1000).animate({ backgroundColor: "#EFEAEA" }, 1500);

Cela peut être appelé par une fonction, "élément" étant la classe d'élément / nom / etc. L'élément apparaîtra instantanément avec l'arrière-plan # FCFCD8, maintiendra pendant une seconde, puis se fondra dans #EFEAEA.



2

Je suis tombé sur cette page avec le même problème, mais les problèmes suivants:

  1. Je ne peux pas inclure un fichier de plugin jQuery supplémentaire avec ma configuration actuelle.
  2. Je ne suis pas à l'aise de coller de gros blocs de code que je n'ai pas le temps de lire et de valider.
  3. Je n'ai pas accès au CSS.
  4. Je n'avais guère de temps pour la mise en œuvre (ce n'était qu'une amélioration visuelle d'une page d'administration)

Avec ce qui précède, cela a pratiquement exclu toutes les réponses. Étant donné que ma décoloration était très simple, j'ai plutôt utilisé le hack rapide suivant:

element
  .css('color','#FF0000')
;
$('<div />')
  .css('width',0)
  .animate(
    {'width':100},
    {
      duration: 3000,
      step:function(now){
        var v = (255 - 255/100 * now).toString(16);
        v = (v.length < 2 ? '0' : '') + v.substr(0,2);
        element.css('color','#'+v+'0000');
      }
    }
  )
;

Ce qui précède crée un div temporaire qui n'est jamais placé dans le flux de documents. J'utilise ensuite l'animation intégrée de jQuery pour animer une propriété numérique de cet élément - dans ce cas width- qui peut représenter un pourcentage (0 à 100). Ensuite, en utilisant la fonction step, je transfère cette animation numérique à la couleur du texte avec une simple cacluation hexadécimale.

La même chose aurait pu être obtenue avec setInterval, mais en utilisant cette méthode, vous pouvez bénéficier des méthodes d'animation de jQuery - comme .stop()- et vous pouvez utiliser easinget duration.

De manière évidente, cela n'est utile que pour les fondus de couleur simples, pour des conversions de couleurs plus compliquées, vous devrez utiliser l'une des réponses ci-dessus - ou coder vos propres calculs de fondu de couleur :)


2

Essaye celui-là:

(function($) {  

            var i = 0;  

            var someBackground = $(".someBackground");  
            var someColors = [ "yellow", "red", "blue", "pink" ];  


            someBackground.css('backgroundColor', someColors[0]);  

            window.setInterval(function() {  
                i = i == someColors.length ? 0 : i;  
                someBackground.animate({backgroundColor: someColors[i]}, 3000);  
                i++;  
            }, 30);  

})(jQuery);  

vous pouvez prévisualiser l'exemple ici: http://jquerydemo.com/demo/jquery-animate-background-color.aspx



1

Si vous ne souhaitez pas animer votre arrière-plan en utilisant uniquement la fonctionnalité jQuery principale, essayez ceci:

jQuery(".usercontent").mouseover(function() {
      jQuery(".usercontent").animate({backgroundColor:'red'}, 'fast', 'linear', function() {
            jQuery(this).animate({
                backgroundColor: 'white'
            }, 'normal', 'linear', function() {
                jQuery(this).css({'background':'none', backgroundColor : ''});
            });
        });

0

Essayez de l'utiliser

-moz-transition: background .2s linear;
-webkit-transition: background .2s linear;
-o-transition: background .2s linear;
transition: background .2s linear;

0

Essaye celui-là:

jQuery(".usercontent").hover(function() {
    jQuery(this).animate({backgroundColor:"pink"}, "slow");
},function(){
    jQuery(this).animate({backgroundColor:"white"}, "slow");
});

Manière révisée avec effets:

jQuery(".usercontent").hover(function() {

    jQuery(this).fadeout("slow",function(){
        jQuery(this).animate({"color","yellow"}, "slow");
    });
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.