views:

187

answers:

3

I'm trying to create a generic 'flash of color confirmation' function where it'll flash the background of an object to green and then fade out to whatever it's existing color was.

So I may have two elements that I call this on click():

li background-color: red
li background-color: black

If I click the first one, it'd fade from green to red. If I click the first one, it'd fade from green to black.

The jQuery logic:

click event:

listItem.each(function(){confirmFlash($(this),$(this).css("backgroundColor"))});

the function:

function confirmFlash(objectToFlash,backgroundColor){
 objectToFlash.css("backgroundColor","#84da9a").animate({opacity: 1}, 1000).animate({backgroundColor: backgroundColor}, 500);
}

This works great. The catch:

If I also give the above LI's a :hover state background color:

li background-color: red
li background-color: black
li:hover background-color: purple

Then all of my fades go from green to purple. That makes sense, since at the time of clicking the LI, the background is, indeed, purple.

Is there a clever way to grab the 'non-hover' CSS class's back-ground color?

A way to reword it is that I'd like to grab the background color assigned to the LI's current class, rather than pseudo class.

Or is the solution to implement the hover not by CSS, but do it via jQuery as well?

A: 

You should really install the color plugin, which will allow you to animate colors directly. Animating the opacity is problematic, because both the text and the background are animated.

see: http://plugins.jquery.com/project/color

John C
I'm confused as to what that plugin does. $.animate seems to work just fine in jQuery with background colors. My issue is that I just need to figure out the proper color to animate to.
DA
A: 

You could store the initial background color in a variable at the time you bind the confirmFlash functionality, something like this...

jQuery.fn.confirmFlash = function(config){
 this.each(function() {
  var elem = jQuery(this);

  // Store the starting background color
  var startBg = elem.css("backgroundColor");

  // When the element is clicked
  elem.click(function() {
   // Set the start background color
   elem.css("backgroundColor", startBg);
   // Animate to the "flash" color
   elem.animate({backgroundColor: config.backgroundColor}, {duration: 1000, complete: function() {
    // Animate back to the start background color
    elem.animate({backgroundColor: startBg}, {duration: 1000});
   }});
  });
 });
};

And then you can use it like this...

$("li").confirmFlash({backgroundColor: "#84da9a"});
joshperry
That's a good idea. Alas, that'd be grabbing the color *too* soon, as I'm also swapping the two colors on click as well. A LI will switch between color A and color B based on changing the class via jQuery. Both get over-ridden by the :hover. But you got me thinking now...hmm....
DA
A: 

Here's what I came up with. I omitted the :hover class from my CSS and created a .hover that I then add or remove via jquery:

function createToggleList(){
 // create mouseovers/outs 
 $("ul.toggleList li").mouseover(function(){
  $(this).addClass("hover");
 });
 $("ul.toggleList li").mouseout(function(){
  $(this).removeClass("hover");
 });  
 // attach the click event
 $("ul.toggleList li").click(function(){toggleToggleListItem($(this))})
};

Then, in the function that is triggered on the click event, I remove the HOVER class, so I can then grab the background it was prior to hover:

function toggleToggleListItem(listItem) {
    listItem.removeClass("hover");
    confirmFlash(listItem,listItem.css("backgroundColor"));
};

And here's the function that creates the flash:

function confirmFlash(objectToFlash,backgroundColor){
 objectToFlash.css("backgroundColor","#84da9a").animate({opacity: 1}, 1000).animate({backgroundColor: backgroundColor}, 500, function(){
  objectToFlash.removeAttr("style");
 });
}

Note that I have to remove the STYLE attribute after animating, as I want the item to inherit from the CSS file again, rather than the new inline style created via the animation.

and that works. Whew!

DA
eh. Spoke too soon. The issue that I keep running into is the fact that jQuery, when animating, is appending in-line styles. I end up with conflicts between colors set in the CSS getting over-ridden by inline styles getting over-ridden if I use !important back in the CSS. So one is always trumping the other. In the end, I'm going to have to handle all the color switching and animating via jQuery alone and skip setting any of it in CSS.
DA
aha! Final answer is now above. The final fix was to remove the !important flags from the css. Then, after animating via jquery, I then remove the STYLE attribute from the element that was just created via the animation, thereby returning any inheritance back to the CSS file.
DA