iamtheratio
iamtheratio

Reputation: 569

jQuery - addClass or removeClass - Is there an append class?

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");
}

Upvotes: 3

Views: 11699

Answers (8)

Luca Filosofi
Luca Filosofi

Reputation: 31173

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

Upvotes: 1

Pointy
Pointy

Reputation: 413702

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".

Upvotes: 2

Armstrongest
Armstrongest

Reputation: 15409

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.

Upvotes: 2

kfiroo
kfiroo

Reputation: 1953

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 */ }

Upvotes: 1

Rony
Rony

Reputation: 9511

.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';
});

Upvotes: 1

Sarfraz
Sarfraz

Reputation: 382656

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.........

Upvotes: 2

philnash
philnash

Reputation: 73029

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.

Upvotes: 0

Jeremy
Jeremy

Reputation: 22415

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.

Upvotes: 0

Related Questions