Nicole McCoy
Nicole McCoy

Reputation: 358

Using jQuery I want to add a class to a div only WHEN another unconnected div exists with a specific class

Okay, so basically I have a Joomla site and a horizontal jQuery nav. I need an arrow ("#selector") to point to the the active top navigation. The nav is in an unordered list. Using jquery I move the arrow on hover (which I want) by assigning a class with the appropriate margin-left value but then once I select that link and it becomes the active parent I need the arrow to stay there until it moves again because of hover action.

So for example:

<style>
#nav li {
list-style: none;
display: inline;
}
#nav_arrow .item-2-selector {
margin-left: 45px!important;
}
</style>

<ul id="nav">
    <li class="item-1 active">Page 1</li>
        <ul>
            <li>SubPage1</li>
            <li>SubPage2</li>
            <li>SubPage3</li>
        </ul>
    <li class="item-2">Page 2</li>
    <li class="item-3">Page 3</li>
    <li class="item-4">Page 4</li>
</ul>

 <div id="nav_arrow">
  <div id="selector" class="position"><img src="nav_current.png"/></div>
</div>

My logic I was hoping to be able to come up with a jQuery solution for was:

WHEN .item-1.active EXIST $("#selector").css('margin-left', '20px');
WHEN .item-2.active EXIST $("#selector").css('margin-left', '45px');
WHEN .item-3.active EXIST $("#selector").css('margin-left', '70px');

...etc...

Basically this is what I'm doing for the hover effect:

<script>

$(document).ready(function(){
$(".item-466").mouseover(function(){
 $("#selector").addClass("item-2-selector");
 });
});
</script>

and here is the URL to my test site so that you can see better exactly what I'm trying to do: http://trustmarkstaging.com

Thanks in advance for any help! :)

Upvotes: 0

Views: 125

Answers (3)

roselan
roselan

Reputation: 3775

var itemsClasses = getItemClasses('#nav li');
var allClasses = itemsClasses.join('-selector ') + '-selector';

console.log(allClasses);
$("#nav li.active").mouseover(function(){
    var itemClass = getItemClasses(this)[0];
    //console.log(itemClass);
    if (itemClass != undefined) {
        $("#selector").removeClass(allClasses).addClass(itemClass+'-selector');
        console.log($("#selector").attr('class'));
    }
});

function getItemClasses(thing) {
    var itemsClasses = [];
    $(thing).each( function () {
        var classAttr = $(this).attr('class');
        if (classAttr != undefined) {
            var itemClasses = classAttr.split(' ');
            for (var i in itemClasses) {
                if ( itemClasses[i].indexOf('item') == 0 ) {
                    itemsClasses.push(itemClasses[i]);
                }
            }
        }
    });
    return itemsClasses;
}

EDIT heavily updated, and here is a working fiddle

as you see, this is heavy. If you can add something like id="item-1" to each li, the code would be tons lighter ;)

It works for any number of li, not only 3, and it assumes the css files got the corresponding "margin-left"s for .item-X-selector. Finally, it's independent of the active state, it assumes the hovered li is the active one.

if you need explanations, just ask ;)

Upvotes: 0

jfriend00
jfriend00

Reputation: 707736

The brute force way is this:

var marginLeft;
if ($(".item-3.active").length > 0) {
    marginLeft = "70px";
} else if ($(".item-2.active").length > 0) {
    marginLeft = "45px";
} else if ($(".item-1.active").length > 0) {
    marginLeft = "20px";
} else {
    marginLeft = 0;
}

$("#selector").css("margin-left", marginLeft);

It was unclear to me whether more than one item could be active which is why I test them in reverse order (looking for the highest numbered item that is active).

A more elegant and extensible method that would work for any number of items might be something like this:

var marginLeft = 0;
var active = $("#nav li.active:last");
if (active.length > 0) {
    marginLeft = ((active.index() * 25) + 20) + "px";
}
$("#selector").css("margin-left", marginLeft);

Upvotes: 1

maxedison
maxedison

Reputation: 17573

You can check if an element exists with jQuery by inspecting the jQuery object's length property. For example:

if($('.item-1.active').length > 0) $("#selector").css('margin-left', '20px');
if($('.item-2.active').length > 0) $("#selector").css('margin-left', '45px');
if($('.item-3.active').length > 0) $("#selector").css('margin-left', '70px');

Upvotes: 0

Related Questions