views:

77

answers:

4

Hello,

I'm working in wordpress, trying to figure out how to change the css color of a side nav element when a remote image is hovered.

I would have done this easily with CSS and just assign the CSS hover class for each item, but since this is a CMS, the navigation and the image gallery will change dynamically.

So, I'm looking for a JQuery of how to accomplish this. Any suggestions?

Here's an example of the html:

<div class="imgGallery">
 <img class="page-item-54" src="/image1.jpg">
 <img class="page-item-66" src="/image2.jpg">
<div>

When someone hovers over the specific image above, it changes the css of the image below:

<ul class="pageNav">
 <li class="page-item-54">Sub Gallery 1</li>
 <li class="page-item-66">Sub Gallery 2</li>
</ul>

Thanks! Troy

A: 

You can FAKE a CSS HOVER with the code bellow

$(document).ready(function() {

    var images = $(".imgGallery img");

    $.each(images, function(i, item) {      
        $(item).mouseover(function() {
            $(this).css({
                "background-image": "url('alternate_image.png')",
                "background-repeat": "no-repeat"
            });
        }).mouseout(function() {
            $(this).css({
                "background-image": "url('original_image.png')"
            });

        });
    });

});
GerManson
+2  A: 

You can use the jQuery hover function to hook up handlers for the mouseenter and mouseleave events of the images (which jQuery will happily simulate on browsers that don't support them):

$(".imgGallery img").hover(
    function() {
        // Code for when the hover starts, the (raw) hovered `img`
        // element is `this`, from which we can get the class name
        // to feed into a selector for finding the relevant `li`
        $(".pageNav ." + this.className).css(/* your change here */);
    },
    function() {
        // Code for when the hover ends, the (raw) unhovered `img` 
        // element is `this`
        $(".pageNav ." + this.className).css(/* your change here */);
    }
);

Here's a live example with just one pageNav, and a revision with multiple pageNavs just to show that it is updating multiple locations simultaneously.

mouseenter and mouseleave (IE innovations that still aren't supported natively by many browsers, but which jQuery provides if missing) are a lot less difficult to work with for this sort of thing than mouseover and mouseout, since mouseover and mouseout bubble. (In your case, it may not matter much, as you're using imgs; if you were using elements that could have child elements, though, it would make a big difference.)

T.J. Crowder
Probably not a worry in this case, but worth noting that calling `$(".pageNav " + this.className)` for each event, could cause performance issues. It would be better to cache `$('.pageNav')` above the `hover` definition as something like `var pageNav = $('.pageNav');` and then use it with `find` as `pageNav.find('.'+this.className).css(/*your change here*/);`
Nate Pinchot
@Nate: The overhead of the event and the user's action will *far* outweigh the overhead of the lookup. And you're assuming that the structure under `pageNav` is static, which it may or may not be... (I assumed the structure under `imgGallery` was.)
T.J. Crowder
@TJ, I agree, the overhead of the lookup is not a big deal in this case. However, correct me if I am wrong, but caching the initial lookup of `$('.pageNav')` and using `find` to locate the `li` children, should indeed work correctly if the structure under `pageNav` changes.
Nate Pinchot
@Nate: *"...caching the initial lookup...and using find...should indeed work correctly if the structure under pageNav changes..."* Yes quite so, for some reason I thought you meant caching each `li`.
T.J. Crowder
Hi Guys, sorry... this didn't work.Any other suggestions?
Troy
@Troy: I was missing two dots (one in each function), it had `$(".pageNav " + this.className).css(...` but it should have been `$(".pageNav ." + this.className).css(...`. Fixed now, with live example.
T.J. Crowder
A: 

In this jQuery script, I add and remove a second class class "over" that you can style accordingly.

$(function () {

    $('div.imgGallery img').hover(
        function () {
            $('ul.pageNav li[class=' + $(this).attr('class') + ']').addClass('over');
        },
        function () {
            $('ul.pageNav li[class=' + $(this).attr('class') + ' over]').removeClass('over');
        });

});
AndrewDotHay
Nope, sorry, didn't work.
Troy
A: 

Here is a possible solution.

You may want to look at changing <ul class="pageNav"> to <ul id="pageNav"> (unless you know for sure you will never duplicate this class).

Edit: updated to allow for multiple classes in the img tag.

$(function() {
    var $pageNav = $('.pageNav');
    // hook up hover function to all images under the imgGallery class
    $('.imgGallery').find('img').hover(function() {
        // find "page-item-" class
        var pageItemClassName = this.className.replace(/.*(page-item-\d+).*/, "$1");
        // toggle hovered class on matching item under unordered list
        $pageNav.find('.' + pageItemClassName).toggleClass('hovered');
    });
});​

You can then make a hovered css class which will apply when hovered. For example:

.pageNav .hovered {
    background-color: #009900;
}
Nate Pinchot
Nope... didn't work.Should I be putting this in the head of the document? That shouldn't matter... right?Also, would it affect it if there were two classes assigned to each item? So, for example, "page_item page-item-54" is the two classes.
Troy
Correct, putting it in the head should not matter. However, having an extra class in there does break the implementation I proposed. I updated the code to work with multiple classes in the `img` tag.
Nate Pinchot
Worked perfectly... thanks Nate!
Troy