views:

724

answers:

8

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");
}
+3  A: 

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

Pointy
Yeah I just wish I knew more about jQuery to make this easier on me, haha. However I just want to add a "_on" on the selected tab, this will make the background positioning change on the image and solve my problem. Is it something like jQuery('.tab#' + stringref).addClass('_on') ? That apparently didn't work either. Any extra help?
iamtheratio
this also didn't work.. jQuery('.tab#' + stringref).addClass('.tab#' + stringreg + '_on');
iamtheratio
Well that's because you're doing it wrong :-) Like I said, jQuery does not provide a direct way to do this. I'll update my answer.
Pointy
+3  A: 

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.........
Sarfraz
Though somewhat confusing, the OP was asking *not* how to add an additional class, but rather how to modify an existing class on an element by appending some additional text. Example: "what" would be changed to "what_on". Pointy's solution (remove and then add the new class) should work.
Peter
@Peter, agreed but i had already mentioned this thing in my answer on top. Thanks
Sarfraz
A: 

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.
Jeremy
+1  A: 
.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';
});
Rony
That's good to know, but I don't think it'd really help because ultimately all that `addClass` will do is add classes - it won't get rid of anything in the class string.
Pointy
A: 

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.

Phil
You have to be careful with .how.on as it doesn't work reliably in older browsers. You should be able to still target in jQuery without problems, however.
Atømix
+1  A: 
Atømix
to be honest I think the best method for me to use would be this one: var oldClass = $(element).className(); $(element).removeClass( oldClass ).addClass(oldClass + '_on'); however.. I tried this and I'm not getting much luck. I'm a beginner at this, so it's taking me a second to get the hang of it. :)
iamtheratio
Yeah, that code is off the top of my head. className will get the name, but it will return ALL the names. You really have to ask yourself what you're trying to accomplish. If it's just CSS Styling, I recommend you try the SIMPLEST method and using style overriding.
Atømix
yeah, i agree but I'm not trying to change the container of the data, just the li a img. I will update the top with more CSS to give you a better view of my li a css. I really appreciate all the help though, thank you.
iamtheratio
UPDATED. This should work, uses little code and should be fairly quick. I would recommend that you make your tab container an ID, however, as they're faster to traverse.
Atømix
This has worked perfectly, thank you so much. I just had to add "id="how_on"" so the original tab was selected on page load, but everything else works flawlessly.
iamtheratio
Happy it helped. It's good to find a different approach to this problem.
Atømix
Do you know if there's a way to automate/animate this? So it's a slideshow, like after a few seconds if tab2 isn't clicked it automatically fades into it?
iamtheratio
Depends on how your site works. Best to outline it in a new question. To get you started: setTimeout( 2000 ) will perform some javascript every 2 seconds. window.location('http://www.page-2.html') will redirect your users to a different page.
Atømix
+1  A: 

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 */ }
kfiroo
This may work by itself, but when i added it with my code above it broke the entire process. Right now the tab switching between DIVs are perfect, I just need the images to change with the clicking of the tabs.
iamtheratio
actually if I just add, this.className += '_on'; this works however then it doesn't turn off when I click on another tab. Hrmm..
iamtheratio
i edited my post check it out now
kfiroo
This changed the image on HOW when I click it, however it doesn't turn off the "on" when I click WHY.
iamtheratio
I guess that's the problem now, if I have 5 tabs, and I click on #1 it's now listed as "on", then if I click #2 it's listed as "on" however #1 was never turned off.
iamtheratio
I have updated the CSS above, this seems to work, I just need the first tab to be actived on page load, then the other tabs to inactivated when you click on another tab.
iamtheratio
editing the post again
kfiroo
+1  A: 

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

aSeptik
Is there a way to automate this, like make tab 1 automatically change to tab2 after a few seconds and so on and so forth? Thanks for all the help!
iamtheratio