views:

247

answers:

2

I'm trying to group related elements using class name. They, in turn, are all related as they are all using the same prefix for the class name. Example:

<ul>
  <li class="category-fruit"></li>
  <li class="category-grain"></li>
  <li class="category-meat"></li>
  <li class="category-fruit"></li>
  <li class="category-meat"></li>
</ul>

Visually, I want a hover function on each that, when hovered, will apply the same visual effect to the other elements sharing the same class name.

While it's easy to select a particular LI with a particular class, how would I go about picking a particular class from the hovered LI?

So in pseudo code

$("li").hover(function(){
    $(this).[get-the-class-beggining-with"category"]
})

I'm guessing this involves using the starts with selector ([attribute^=value])

+2  A: 

You can use the attributeStartsWith selector:

$("li[class^=category]").hover(/*...*/);

Check an example with your markup here.

Edit: To get the class name you can use this.className or, use the attr function, for example:

$("li[class^=category]").each(function(){
  var className = $(this).attr('className');  
  // this.className, or attr('class'), which will be mapped to className
});

And by the way, you can also use the filter(fn) method to select the li elements which their className starts with 'category':

$("li").filter(function () {
  return /category-.+/.test(this.className);
}).hover(/*...*/);
CMS
that will select the dom object with that class, but what if I want to grab the entire class name itself?
DA
$( 'li' ).attr( 'class' );
Jacob Relkin
Inside the `hover` function, `this.className` will be the fastest way of getting all the classes applied to the current `li`. If there is only one, then great. If not, filtering still has to be applied.
Doug Neiner
Just noticed your JSBin link... very cool! I really need to start using that!
Doug Neiner
+1  A: 

Following @CMS's awesome lead, I have posted a working example of this solution to JSBin.

I have come up with a solution that allows you to have additional classes on the li's and, after it finds the correct siblings it caches it for future use to speed up the execution:

$(function(){
    $("li").hover(function(){
        var $this    = $(this),
            $cache   = $this.data('hoverCache');

        if(!$cache){
            var category = this.className.match(/category\-.+?\b/)  
            $this.data('hoverCache', $this.siblings('.' + category).andSelf().addClass('hover') );
        } else {
         $cache.addClass('hover');
        }

    }, function(){
        var $cache = $(this).data('hoverCache');
        if($cache) $cache.removeClass('hover');
    });
})

So it doesn't get lost in this optimized example, here is the relevant code to your question:

var category = this.className.match(/category\-.+?\b/);
$(this).siblings('.' + category).andSelf();

This finds the category from the className (there can be additional classes) and then it finds other children of the same parent using .siblings and then includes itself so you can add the hover class to the elements at one time.

I tested this code using Firefox and your provided HTML and it worked great. Let me know if its not what you needed!

Doug Neiner
thanks. I'll have to study this for a bit but looks interesting!
DA
@DA I updated my answer so you can just skip to the relevant parts relating to your question. Let me know if that is clearer.
Doug Neiner
@dcneiner ah! yes, that does clarify things. Clever! Thanks!
DA
@dcneiner I noticed you use both 'this' and '$(this)'. Can you explain the difference?
DA
**@dcneiner:** +1, nice example, JSBin is a great resource!, **@DA:** with `this` you access the raw DOM element, with `$(this)` you can use jQuery specific methods on that element.
CMS
Thanks @CMS! Great clarification of `this` and `$(this)`. Also, I normally store the result of `$(this)` in a variable if I plan on using it more than once and I can't chain it. In those cases you will see `$this` in my code.
Doug Neiner