Question

I have css hover over images for my tabs and I'm trying to get the class to change from .how to .how_on when I click on the image HOW.

My tabs are

HOW | WHAT | WHEN | WHO | WHY

I have classes for each (.how, .how_on), (.what, .what_on), etc...

Can I make jQuery add _on to the original class name using click(function(){}); ?

HTML:

<div id="tab_container">
     <ul class="tabs">
        <li><a class="how_on" href="#how">How</a></li>
        <li><a class="why" href="#why">Why</a></li>
        <li><a class="what" href="#what">What</a></li>
        <li><a class="who" href="#who">Who</a></li>
        <li><a class="when" href="#when">When</a></li>
    </ul>
    <p><img src="images/tab_top.jpg" width="864px" height="6px" alt="" border="0" /></p>
</div>
<div class="tab_body">
    <!-- HOW -->
        <div id="how" class="tab">
            <strong>HOW IT WORKS:</strong>
        </div>

JQUERY:

<script type="text/javascript">
jQuery(document).ready(function(){
 //if this is not the first tab, hide it
 jQuery(".tab:not(:first)").hide();
 //to fix u know who
 jQuery(".tab:first").show();
 //when we click one of the tabs
 jQuery(".tabs a").click(function(){
 //get the ID of the element we need to show
 stringref = jQuery(this).attr("href").split('#')[1];




 // adjust css on tabs to show active tab





 //hide the tabs that doesn't match the ID
 jQuery('.tab:not(#'+stringref+')').hide();
 //fix
 if (jQuery.browser.msie && jQuery.browser.version.substr(0,3) == "6.0") {
 jQuery('.tab#' + stringref).show();
 }
 else
 //display our tab fading it in
 jQuery('.tab#' + stringref).fadeIn();
 //stay with me
 return false;
 });

});
</script>

CSS:

.tabs
{
    width: 683px;
    height: 29px;
    padding: 0;
    margin: 0;
    display: inline;
    float: left;
    overflow: hidden;
    list-style-type: none;
}

.tabs li
{
    margin: 0;
    padding: 0;
    display: inline;
    float: left;
}

.tabs  a {  background-position: 0 -58px;}
.tabs .on a {   background-position: 0 -29px;}

.how,
a.how:link,
a.how:visited
{
  float: left;
  display: inline;
  width: 135px;
  height: 29px;
  margin: 0;
  text-decoration: none;
  text-indent: -99999px;
  overflow: hidden;  
  background-image: url("../images/how_tab.jpg");
}
Was it helpful?

Solution

UPDATED:

Try this:

$('.tabs a').click(function() {
    $('.tabs a').removeAttr('id'); // remove all ids
    $(this).attr('id', this.className + "_on") // create how_on as this id.
});

You're using the Classname to create a Unique ID. It will accomplish the same thing that you're trying to do. Here's a sample with "why" selected.

 <ul class="tabs">
    <li><a class="how" href="#how">How</a></li>
    <li><a id='why_on' class="why" href="#why">Why</a></li>
    <li><a class="what" href="#what">What</a></li>
    <li><a class="who" href="#who">Who</a></li>
    <li><a class="when" href="#when">When</a></li>
 </ul>

Of course, THE SIMPLEST WAY is to add the .how_on class and have both classes.

<div class='how how_on'>some stuff</div>

Nothing wrong with that and you can easily override styles or target the element.

.how { color: #000; }
div.how_on { color: #F00; } /* increased specificity */

If you want to make sure it overrides it, increase the specificity.

OTHER TIPS

When you use addClass, it adds/appends a class unless you remove some first using removeClass, so you do like this:

$('.how_on').mouseover(function(){
    $(this).removeClass('class_name').addClass('class_name');
});

$('.why').mouseover(function(){
    $(this).removeClass('class_name').addClass('class_name');
});

// and so on.........

I wish jQuery did have that, but as far as I can tell it doesn't. You can always use removeClass to get rid of one version and addClass to add the other. Alternatively, you could cook up your own little plugin. Seems like a useful thing to do; even jQuery UI has to deal with munging all its classes ("ui-state-default", "ui-state-hover", etc) and it'd be easier if it could just call an API to update the class stem "ui-state-" with a chosen suffix.

Thus, the simple jQuery way to do it in your case would be something like:

// to go from "foo" to "foo_on":
function turnOn(which) {
  $('.tabs').find('a.' + which)
    .removeClass(which)
    .addClass(which + '_on');
};

// to go from "foo_on" to "foo"
function turnOff(which) {
  $('.tabs').find('a.' + which + '_on')
    .removeClass(which + '_on')
    .addClass(which);
}

You'd then call turnOn("how") when you want the "how" tab to switch to class "how_on", and turnOff("how") to make it go from "how_on" to "how".

.addClass( function(index, class) )

addClass takes an anonymous function and you can add the logic to append the class here

like

$('ELEMENT SELECTION').addClass(function() {
  return $(this).attr("class") + 'CLASS TO BE ADDED';
});

you can always do:

jQuery(".tabs a").click(function(){
    this.className += '_on';
}

which will add the desired suffix.

even better will be to add the "activation" class to the containing 'li'.

jQuery(".tabs a").click(function(){
    $(this).parent().toggleClass('on');
}

and your css should look like this:

/* here i removed the 'a.how_on' entry */
.how,
a.how:link,
a.how:visited
{
  float: left;
  display: inline;
  width: 135px;
  height: 29px;
  margin: 0;
  text-decoration: none;
  text-indent: -99999px;
  overflow: hidden;  
}

a.how:visited, a.how:link, a.how:hover
{
    background-image: url("../images/how_tab.jpg");
    background-position: 0 -58px;
}

/* this will cause the link to behave different when its parent is of class on */
.on a.how
{
    background-image: url("../images/how_tab.jpg");
    background-position: 0 -29px;
}

and you can define a general behavior for your tabs link this

.tabs a { /* style */ }
.tabs a:link { /* link style */ }
.tabs a:hover { /* hover style */ }

.tabs .on a { /* activated style */ }
.tabs .on a:link { /* activated link style */ }
.tabs .on a:hover { /* activated hover style */ }

You Can Completely Replace your jQuery Part with this;

This must work as expected!

JAVASCRIPT PART

$(function() {

    var tabs = $('div.tab_body > div.tab');
    tabs.hide().filter(':first').show();

    $('div#tab_container ul.tabs a').click(function() {
        tabs.hide();
        var myhash = this.hash.split('#')[1];

        tabs.filter(this.hash).show();

        $('a:not(.' + myhash + '_on)').each(function() {
            var h = this.hash.split('#')[1];
            $(this).removeClass(h + '_on').addClass(h);
        });
        $(this).removeClass(myhash).addClass(myhash + '_on');

        return false;
    }).filter(':first').click();
});

HTML PART

<div id="tab_container">
 <ul class="tabs">
    <li><a class="how" href="#how">How</a></li>
    <li><a class="why" href="#why">Why</a></li>
    <li><a class="what" href="#what">What</a></li>
    <li><a class="who" href="#who">Who</a></li>
    <li><a class="when" href="#when">When</a></li>
</ul>            
</div>

<div class="tab_body">
    <div id="how" class="tab">
        <strong>how</strong>
    </div>
    <div id="why" class="tab">
        <strong>why:</strong>
    </div>
    <div id="what" class="tab">
        <strong>what</strong>
    </div>
    <div id="who" class="tab">
        <strong>who</strong>
    </div>
    <div id="when" class="tab">
     <strong>when</strong>
    </div>
  </div>

Hope this help!

Regards

There are a few approaches.

  1. Remove the class, append _on to the string and add the new class.
  2. Simply design your *_on classes to modify the original classes styles. Then all you have to do is remove the *_on class to revert to the old style.

Why don't you just add the class on to the elements in question and change your CSS rules from .how and .how_on to .how and .how.on?

Then, in your .how.on you can just override anything set in the .how that you want to change.

I don't think you need to bend JavaScript/jQuery to your will, rather use CSS specificity for what it was meant for.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top