jQuery animar fondo Color


327

Estoy tratando de animar un cambio en backgroundColor usando jQuery en el mouseover.

He comprobado algún ejemplo y parece que lo tengo bien, funciona con otras propiedades como fontSize, pero con backgroundColor obtengo y el error js "Invalid Property". El elemento con el que estoy trabajando es un div.

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

¿Algunas ideas?


Para jquery 1.4.2 con efecto jquery 1.8, debo admitir que la solución de Andrew funciona perfectamente. Ver su publicación a continuación.
Patrick Desjardins

1
Nota: este complemento detecta el color de fondo actual del elemento: el navegador Chrome devuelve en rgba(0, 0, 0, 0)lugar del valor vacío / nulo esperado cuando no hay un color de fondo definido. Para "arreglar" esto, el elemento debe tener un color de fondo inicial.
Shadow Wizard es Ear For You el

La página vinculada parece rota (al menos la página del proyecto y la página de demostración).
Paolo Stefan

Respuestas:


333

El complemento de color es solo 4kb mucho más barato que la biblioteca UI. Por supuesto, querrás usar una versión decente del complemento y no alguna cosa vieja con errores que no maneje Safari y se bloquee cuando las transiciones son demasiado rápidas. Como no se suministra una versión minificada, puede probar varios compresores y hacer su propia versión mínima. YUI obtiene la mejor compresión en este caso, necesita solo 2317 bytes y, dado que es tan pequeño, aquí está:

(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
Muy bien, ve al enlace que Andrew propone. Descargar el archivo. Necesita agregarlo a su proyecto. Todavía puede tener jquery.effects.core en su proyecto, esto funcionará perfectamente. Gracias por la respuesta. +1
Patrick Desjardins

3
Simplemente pegué lo anterior en mi archivo 'jquery-ui-1.8.2.min.js' existente y ... todo seguía funcionando :-)
Dave Everitt

77
Me gustaría señalar que, en el último año (2011), el autor de este complemento lanzó una versión 2 que tiene muchas características agradables, pero no son necesarias para la funcionalidad básica que generalmente se busca para esta lib. Ahora tiene más de 20 kb. Puede seleccionar la v1rama para obtener la versión anterior (que todavía funciona) pero es mucho más ligera.
Aren

66
FWIW: puede eliminar las asignaciones de color a rgb en el código y reducir aún más el tamaño: raw.github.com/gist/1891361/… . La desventaja es que no puede usar nombres de colores para la animación. Tendrás que usar valores rgb.
Niyaz

44
jQuery 1.8 rompe este enchufe por cierto. curCSS ya no está en jQuery.
Rich Bradshaw

68

Tuve el mismo problema y lo solucioné incluyendo jQuery UI. Aquí está el guión completo:

<!-- 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

Hazlo con CSS3-Transitions. El soporte es excelente (todos los navegadores modernos, incluso IE). Con Compass y SASS esto se hace rápidamente:

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

CSS puro:

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

Escribí un artículo en alemán sobre este tema: http://www.solife.cc/blog/animation-farben-css3-transition.html


66
Violín con la libración y clic transiciones en: jsfiddle.net/K5Qyx
Dem Pilafian

30

Bitstorm tiene el mejor complemento de animación de color jquery que he visto. Es una mejora para el proyecto de color jquery. También es compatible con rgba.

http://www.bitstorm.org/jquery/color-animation/


1
No puedo agradecerles lo suficiente por afirmar que es compatible con 'rgba', que es exactamente lo que estaba buscando
Onimusha

13

Puede usar jQuery UI para agregar esta funcionalidad. Puede obtener justo lo que necesita, por lo que si desea animar el color, todo lo que tiene que incluir es el siguiente código. Obtuve si de la última interfaz de usuario jQuery (actualmente 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);
};

Es solo 1.43kb después de comprimir con 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)};

También puede animar colores usando transiciones CSS3, pero solo es compatible con navegadores modernos.

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;
  }

Usando la propiedad abreviada:

/* 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;
 }

A diferencia de las transiciones regulares de JavaScript, las transiciones CSS3 son aceleradas por hardware y, por lo tanto, más suaves. Puede usar Modernizr, para averiguar si el navegador admite transiciones CSS3, si no lo hizo, puede usar jQuery como alternativa:

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

Recuerde usar stop () para detener la animación actual antes de comenzar una nueva, de lo contrario, cuando pase el elemento demasiado rápido, el efecto seguirá parpadeando durante un tiempo.


11

Para cualquiera que encuentre esto. Es mejor usar la versión de jQuery UI porque funciona en todos los navegadores. El complemento de color tiene problemas con Safari y Chrome. Solo funciona a veces.


66
-1 La última versión del complemento de color funciona perfectamente en Chrome.
Andrew

3
Es pesado incluir script adicional para animar el fondo
oneiros

11

Puedes usar 2 divs:

Podría poner un clon encima y desvanecer el original mientras desvanece el clon.

Cuando terminen los fundidos, restaure el original con el nuevo 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);
    });
});​

Ejemplo de jsFiddle


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


tal vez funcionó en algún momento, al menos correcto, no parece hacer lo que se espera de él.
epeleg

@epeleg: funciona en Mac Chrome para mí. Hace clic en el rectángulo coloreado y cambia de color (2013 - 07 - 15)
Peter Ajtai

No sé cómo, pero ahora sí funciona en mi Windows 7 Chrome. ¿Quizás relacionado con la actualización de Chrome que hice el día de ayer? de todos modos, como dije, de hecho funciona ahora.
Epeleg

8

Usé una combinación de transiciones CSS con JQuery para obtener el efecto deseado; obviamente, los navegadores que no admiten transiciones CSS no se animarán, pero es una opción liviana que funciona bien para la mayoría de los navegadores y para mis requisitos es una degradación aceptable.

Jquery para cambiar el color de fondo:

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

CSS usando la transición para desvanecer el cambio de color de fondo

   .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

En estos días, el complemento de color jQuery admite los siguientes colores con nombre:

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
¿Podría por favor citar la fuente? Gracias por el listado por cierto.
Shrikant Sharat el

Esta lista vino del complemento de color jQuery: plugins.jquery.com/project/color
spoulson

2
-1 Tu lista de colores se refiere a una versión desactualizada. La versión actual tiene al menos un color extra que noté.
Andrew

5

Me gusta usar delay () para hacer esto, aquí hay un ejemplo:

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

Esto puede ser llamado por una función, con "elemento" siendo el elemento clase / nombre / etc. El elemento aparecerá instantáneamente con el fondo # FCFCD8, manténgalo presionado por un segundo y luego se desvanecerá en #EFEAEA.



2

Me encontré con esta página con el mismo problema, pero con los siguientes problemas:

  1. No puedo incluir un archivo de complemento jQuery adicional con mi configuración actual.
  2. No me siento cómodo pegando grandes bloques de código que no tengo tiempo de leer y validar.
  3. No tengo acceso al css.
  4. Casi no tuve tiempo para la implementación (solo fue una mejora visual para una página de administración)

Con lo anterior que prácticamente descartó cada respuesta. Teniendo en cuenta que mi desvanecimiento de color era muy simple, utilicé el siguiente truco rápido:

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');
      }
    }
  )
;

Lo anterior crea un div temporal que nunca se coloca en el flujo de documentos. Luego uso la animación incorporada de jQuery para animar una propiedad numérica de ese elemento, en este caso width, que puede representar un porcentaje (0 a 100). Luego, utilizando la función de paso, transfiero esta animación numérica al color del texto con una simple valoración hexadecimal.

Lo mismo podría haberse logrado con setInterval, pero al usar este método puede beneficiarse de los métodos de animación de jQuery, como .stop(), y puede usar easingy duration.

Obviamente, solo es útil para desvanecimientos de color simples, para conversiones de color más complicadas necesitará usar una de las respuestas anteriores, o codificar sus propias matemáticas de desvanecimiento de color :)


2

Prueba este:

(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);  

Puedes ver un ejemplo aquí: http://jquerydemo.com/demo/jquery-animate-background-color.aspx



1

Si desea animar su fondo usando solo la funcionalidad principal de jQuery, intente esto:

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

Intenta usarlo

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

0

Prueba este:

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

Forma revisada con efectos:

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

    jQuery(this).fadeout("slow",function(){
        jQuery(this).animate({"color","yellow"}, "slow");
    });
});
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.