views:

724

answers:

4

I'm even stated surprised about jQuery's dumb way to put a hover attribute on an element. Take a look at this sample CSS:

div.test
{
   width: 20px;
   height: 20px;
   color: #000000;
   background: #FFFFFF;
}
div.test:hover
{
   color: #FFFFFF;
   background: #CC0000;
}

If we'd like to convert this to jQuery, we have to type the following:

$('div.test').css({
   'width' : '20px',
   'height' : '20px',
   'color' : '#000000',
   'background' : '#FFFFFF'
});
$('div.test').hover(function() {
   $(this).css({
      'color' : '#FFFFFF',
      'background' : '#CC0000'
   });
}, function() {
   $(this).css({
      'color' : '#000000',
      'background' : '#FFFFFF'
   });
});

Arn't there any better way to do this? It feels stupid to write obvious things.

Thank you in advance.

+15  A: 

You're approaching this the wrong way. You'd define a CSS class like so

.highlighted
{
   color: #FFFFFF;
   background: #CC0000;
}

$('div.test').hover(function() {
    $(this).addClass('highlighted');
}, function() {
    $(this).removeClass('highlighted');
});
Praveen Angyan
I'm just able to JavaScript at this moment. And this is exactly the same thing in exception that you've put the style attributes in a CSS class instead. Thank you anyway.
Ivarska
What does "just able to Javascript" mean? You can't CSS your page? What kind of ridiculous restriction is that? The accepted, correct way of doing what you're asking is exactly what is described here. Messing around with direct CSS styles instead of classes is not even remotely needed for this situation...
Paolo Bergantino
He's not "just putting the style attributes in a CSS class", he's putting the CSS in a stylesheet and manipulating the element's classes instead of its styling. That's called abstraction and saves you time.I suggest you learn some best practices in seperation of style, behaviour and content, mate.
Alan
This is getting really annoying. Now read carefully so you guys don't misunderstand anything again: I'm creating a module for our website which displays a JavaScript window (as the alert box but with more opportunities). I want to gather the code of this module in a single file to avoid having to include multiple files when I want to use this module, and in this way keep a good structure while the browser just have to download 1 file instead of 2. Are we all clear?
Ivarska
Firstly, please watch your tone. You weren't being very clear about your problem, so don't be offended if people do not follow.Secondly, it's mostly a bad idea to hard-code the styling in JavaScript (separation of style and behaviour, and all that shtick), hence the suggestion to use a class to be applied to the hovered element (kinda like the `:hover` pseudo-selector). That way you can re-use your code for other hover effects AND you only have one place to look if you want to change the styling: your stylesheet, where it SHOULD be.
Alan
@Alan: Allright, sorry about my bad tone. It seems like I'll have to solve this by myself, even when Pim's code was on the right way.
Ivarska
What do you mean "solve"? Several people have told you the correct way to do this, your stubbornness and attitude is the only thing that needs "solving"
micmcg
@micmcg: Sorry, but what is it you don't understand? I've already told you my reason to make a module completely in JS. I've worked with websites in five years and I know that it's not the "correct" way to do it, but in this case it seems to be the best way and I see no problem with using JS to style something that's made of JS to optimize loading time and structure. And about my "attitude", it seems like you can't handle a critical person. I'm not angry, I'm just arguing. If you could peruade me then go ahead, but stop with these "attitude" attacks. So let's just get back on topic, shall we?
Ivarska
+3  A: 

Also you could just write the following simple plugin to do what you want (automatic unhovering):

$.fn.easyHover = function(cssProps){
   return this.each(function(){
       var $t = $(this);
       var oldProps = {};
       for(x in cssProps)
          oldProps[x] = $t.css(x);
       $t.hover(function(){
          $(this).css(cssProps);
       }, function(){
          $(this).css(oldProps);
       });
   }
}

You could then use it like this:

$('#elem').easyHover({color:'#000', background:'#ccc'});

However Praveen's answer is defenitly the way to go.

Pim Jager
This is more like what I'm looking for, but it seems like it's not working?
Ivarska
+3  A: 

Where you're mistaken is in thinking jQuery tries to replace CSS.

jQuery doesn't "add a hover tag", it merely provides handlers for JavaScript's hover event (IIRC it's actually an abstraction of mouseover/mouseout). If you want to emulate CSS's hover pseudo-selector with JS, jQuery makes it easy for you by giving you an easy-to-use event handler binding.

Alan
Exactly, JQuery isn't magic.
Soviut
I'm not new with jQuery and I know the way it works. What I mean is that jQuery is so smart in all ways except this simple point.
Ivarska
@lvarska: There are many people trying to help you both practically and conceptually, yet you remain indignant. What's up with that?
Chris Farmer
@Chris: Yeah, it feels like you guys underrate me and think I'm dumb, and that annoys me since I multiple times tries to explain what I really mean. Anyway, I really appreciates your time.
Ivarska
jQuery isn't CSS. jQuery allows applying CSS dynamically, that's all.If you use the `:hover` pseudo-selector in jQuery, you get the same elements that would be affected by a CSS rule *at that exact moment*. What the browser does is that it checks the DOM tree every time it changes to update the styling according to the stylesheet. If jQuery did this, it would be emulating the browser IN the browser. It's easy to see why this is a bad idea. So instead, it only provides you with a *really easy-to-use* shortcut to bind event handlers. Fair enough, no?
Alan
@Alan: Thanks, I allready knew that and unfortunately I see this as offtopic. Please stop try to, in vain, explain what jQuery is and does. My question is how to simplify my code in the first post. Read my other posts if my point isn't clear enough. Thank you.
Ivarska
+1  A: 

I suppose another way to go would be the following:

// In you stylesheet, just define the default properties
div.test
{
   width: 20px;
   height: 20px;
}

Then, make a simple object wrapper to hold the properties you want to use

var hoverHelper = (function () {
   var styles = {
      hoverStyle: {
         'color' : '#FFFFFF',
         'background' : '#CC0000'
      },
      defaultStyle: {
         'color' : '#000000',
         'background' : '#FFFFFF'
      }
   };

   return {
      init: function (selector) {
         $(selector).hover(
            function () {
               $(this).css(styles.hoverStyle);
            },
            function () {
               $(this).css(styles.defaultStyle);
            }
         );
      }
   };
}());

hoverHelper.init('.hoverElementClass'); // Apply the hover functions
                                        // to all matching elements

This way, at least you keep the style definitions in one place.

PatrikAkerstrand
I'll see what I can do. Thank you!
Ivarska