tags:

views:

226

answers:

5

Hello,

I have been searching but have come up blank and i'm wondering if I can use one jQuery statement to target multiple elements on a page. I have several identical buttons on a page and they are each made up of a left, middle and right background where the middle contains the text and can expand to any size necessary. Each has a unique Id and/or Class. I have it setup now so that when you mouse over their container div the 3 backgrounds change to give the appearance that the buttons are in a different state. The way its done now is with 1 hover call for each button which is located by Class (would rather use ID but you can't have multiple elements with the same ID). This hover is followed by 8 events. A background change for each right left and middle and a color change for the middles text.

This means lots of lines of code. What I want is to be able to call all the buttons at once with the hover event or to have the hover event somehow know which button is being hovered over and to throw that class or id or even name back to jQuery which can then change the buttons subclasses for right left and middle. The subclass for right left and Middle are identical on all the buttons so if the hover event could be focused on whatever event called it i'd only need one set of calls to change the background attributes... The current code is below for two of the buttons...

$j(".learnMoreButton").hover(
    function () { 
        $j('.learnMoreButton .buttonLeft').css({background:"url(/images/concaveBtn-Left2.gif)"}); 
        $j('.learnMoreButton .buttonMiddle').css("background-image", "url(/images/concaveBtn-Middle2.gif)"); 
        $j('.learnMoreButton .buttonMiddle a').css({color:"#ffffff"});
        $j('.learnMoreButton .buttonRight').css({background:"url(/images/concaveBtn-Right2.gif)"});
    }, 
    function () { 
        $j('.learnMoreButton .buttonLeft').css({background:"url(/images/concaveBtn-Left.gif)"});
        $j('.learnMoreButton .buttonMiddle').css("background-image", "url(/images/concaveBtn-Middle.gif)"); 
        $j('.learnMoreButton .buttonMiddle a').css("color", "#666");
        $j('.learnMoreButton .buttonRight').css({background:"url(/images/concaveBtn-Right.gif)"});
        }
    );

$j(".bioButton").hover(
    function () { 
        $j('.bioButton .buttonLeft').css({background:"url(/images/concaveBtn-Left2.gif)"}); 
        $j('.bioButton .buttonMiddle').css("background-image", "url(/images/concaveBtn-Middle2.gif)"); 
        $j('.bioButton .buttonMiddle a').css({color:"#ffffff"});
        $j('.bioButton .buttonRight').css({background:"url(/images/concaveBtn-Right2.gif)"});
    }, 
    function () { 
        $j('.bioButton .buttonLeft').css({background:"url(/images/concaveBtn-Left.gif)"});
        $j('.bioButton .buttonMiddle').css("background-image", "url(/images/concaveBtn-Middle.gif)"); 
        $j('.bioButton .buttonMiddle a').css("color", "#666");
        $j('.bioButton .buttonRight').css({background:"url(/images/concaveBtn-Right.gif)"});
        }
    );

Thank you in advance for any help.

+4  A: 

You can do:

$(".learnMoreButton, .bioButton").hover(function() {
  $(this).find(".buttonRight")...
  ...
}, function() {
  ...
});

I will add that I think you'd be better off doing that with CSS classes.

.buttonLeft { background: url(/images/concaveBtn-Left.gif) }
.buttonMiddle { background-image: url(/images/concaveBtn-Middle.gif) }
.buttonMiddle a { color: #666; }
.buttonRight { url(/images/concaveBtn-Right.gif) }
.hoverover .buttonLeft { url(/images/concaveBtn-Left2.gif) }
.hoverover .buttonMiddle { url(/images/concaveBtn-Middle2.gif) }
.hoverover .buttonMiddle a { color: #FFF; }
.hoverover .buttonRight { background: url(/images/concaveBtn-Right2.gif) }

and

$(".learnMoreButton, .bioButton").hover(function() {
  $(this).addClass("hoverover");
}, function() {
  $(this).removeClass("hoverover");
});

and you'll have a lot less code.

Also you can give elements multiple classes so:

<div class="bioButton hoverbutton">
  ...
</div>
<div class="learnMoreButton hoverbutton">
  ...
</div>

and then it becomes even simpler:

$(".hoverbutton").function() {
  $(this).addClass("hoverover");
}, function() {
  $(this).removeClass("hoverover");
});
cletus
I believe this is on the right track but the problems I'm having (implementing this) are: Each button has to have 3 subclasses to be expandable. And I need to Target the Subclasses to change their respective classes. As of right now it changes every button when you hover over any one button. With this code... I can't use the "this" in $(this).addClass("hoverover"); because it targets the class hoverButton which is on every hover button. I need a way to target just the specific button being hovered over. You may have explained this but I must have missed it somehow...
Tony C.
@Tony: `this` *absolutely` is *only* the element being hovered over. It's hard to comment on whats going on without seeing the markup/code.
cletus
I'll post my new code as an answer since I can't fit it in 600 characters...
Tony C.
A: 
$j(".learnMoreButton, .bioButton").hover(
    function () {
        var $this = $j(this); //this points to DOM element hovered, $j() makes jQuery object out of it.
        //this syntax tells jQuery to search only inside $this element.
        $j('.buttonLeft', $this).css({background:"url(/images/concaveBtn-Left2.gif)"}); 
        $j('.buttonMiddle', $this).css("background-image", "url(/images/concaveBtn-Middle2.gif)"); 
        $j('.buttonMiddle a', $this).css({color:"#ffffff"});
        $j('.buttonRight', $this).css({background:"url(/images/concaveBtn-Right2.gif)"});
    }, 
    function () { 
        var $this = $j(this);
        $j('.buttonLeft', $this).css({background:"url(/images/concaveBtn-Left.gif)"});
        $j('.buttonMiddle', $this).css("background-image", "url(/images/concaveBtn-Middle.gif)"); 
        $j('.buttonMiddle a', $this).css("color", "#666");
        $j('.buttonRight', $this).css({background:"url(/images/concaveBtn-Right.gif)"});
    }
);
vava
Listen to cletus though, you'll be better off with custom classes. And adding common extra class `hover-button` to all your buttons will make it even better. (You can add multiple classes to one element with `class="class1 class2"`)
vava
A: 

Currently the code looks like this:

$j(function (){  
    $j(".hoverBTN").hover( 
    function() {
        $j(this).addClass("hoveroverL");
        $j(this).addClass("hoveroverM");
        $j(this).addClass("hoveroverR");
    }, function() {
        $j(this).removeClass("hoveroverL");
        $j(this).removeClass("hoveroverM");
        $j(this).removeClass("hoveroverR");
    });

});   

Which works but on the wrong elements. It currently changes the button being hovered over but it adds 3 classes to the buttons wrapper not to the sub classes for Right Left And Middle: An example of the button is:

<div id="timelineButton" style="position:relative;" class="hoverBTN" >
    <div class="buttonLeft"></div>
    <div class="buttonMiddle">Timeline</div>
    <div class="buttonRight"></div>
</div>
Tony C.
Tony, you don't need to add the classes to the child divs. Reread my answer and you'll see you can define a CSS rule of say `.timelineButton .buttonLeft {...}`. That means "find all the `.buttonLeft` descendants of `.timelienButton` and apply these styles.
cletus
It just hit me today what you meant by having multiple classes on each. I was working on something else and had an Oh Yeah Moment... I changed my code again and made it even smaller using your example. Thanks again Cletus
Tony C.
A: 

You may also want to consider not using jQuery or Javascript at all for this. CSS should be sufficient. Just give each button the same class and do something like this in your CSS:

.button .buttonLeft
{
    background: url(/images/concaveBtn-Left.gif)
}

.button .buttonMiddle
{
    background: url(/images/concaveBtn-Middle.gif);
    color: #666;
}

.button .buttonRight
{
    background: url(/images/concaveBtn-Right.gif)
}

.button:hover .buttonLeft
{
    background: url(/images/concaveBtn-Left2.gif)
}

.button:hover .buttonMiddle
{
    background: url(/images/concaveBtn-Middle2.gif);
    color: #ffffff;
}

.button:hover .buttonRight
{
    background: url(/images/concaveBtn-Right2.gif)
}

There is one caveat, however; IE (at least some versions?) doesn't support :hover on divs. The way I work around this is by making a button an <a> and place the elements to be styled inside of the button as <span>s.

Jacob
A: 

Ok I got this working! Thanks Cletus you sent me in the right direction... I had to use the children selector on this, then choose each child and change its individualy classes... Heres the code...

$j(function (){  
$j(".hoverBTN").hover( 
function() { 
    $j(this).children('div:nth-child(1)').addClass("hoveroverL");
    $j(this).children('div:nth-child(2)').addClass("hoveroverM");
    $j(this).children('div:nth-child(3)').addClass("hoveroverR");
}, function() {
    $j(this).children('div:nth-child(1)').removeClass("hoveroverL");
    $j(this).children('div:nth-child(2)').removeClass("hoveroverM");
    $j(this).children('div:nth-child(3)').removeClass("hoveroverR");
});

});

Works perfectly this way. I wanted something compact and easily reuseable and i think this covers both. Thanks again everyone...

Tony C.