HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Showing one category and hiding two others when one of three buttons is clicked

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
threeshowingothershidingbuttonsonetwowhenandclicked

Problem

How can I refactor this code? I know it's repetitive but I'm not sure how to fix it.

$(function() {
    $('#category-1-button a').bind('click', function() {
        $(this).css({opacity:'1'});
        $('#category-2-button a,#category-3-button a').css({opacity:'0.4'});
        $('#blog-headers').css({backgroundPosition: '0 0'});
        $('#category_2,#category_3').hide(0, function() {
            $('#category_1').show(0);
        });
    });
});

$(function() {
    $('#category-2-button a').bind('click', function() {
        $(this).css({opacity:'1'});
        $('#category-1-button a,#category-3-button a').css({opacity:'0.4'});
        $('#blog-headers').css({backgroundPosition: '0 -144px'});
        $('#category_1,#category_3').hide(0, function() {
            $('#category_2').show(0);
        });
    });
});

$(function() {
    $('#category-3-button a').bind('click', function() {
        $(this).css({opacity:'1'});
        $('#category-1-button a,#category-2-button a').css({opacity:'0.4'});
        $('#blog-headers').css({backgroundPosition: '0 -288px'});
        $('#category_1,#category_2').hide(0, function() {
            $('#category_3').show(0);
        });
    });
});

Solution

Give each #category-n-button a class like category_button.

Bind the handler in the each()[docs] method so that you can use the index argument to calculate the background position.

Use this to reference the element that received the event in the click handler.

Use the not()[docs] method to exclude the this element from the other category buttons when setting the opacity.

Use the filter()[docs] method to show the category element that pertains to the index of .each() + 1.

$(function() {
    var categories = $('[id^="category_"]');
    var category_buttons_a = $('.category_button a').each(function( idx ) {
        $(this).bind('click', function() {
            $(this).css({opacity:'1'});
            category_buttons_a.not(this).css({opacity:'0.4'});
            $('#blog-headers').css({backgroundPosition: '0 ' + (idx * -144) + 'px'});
            categories.hide().filter( '#category_' + (idx + 1) ).show();
        });
    });
});

Code Snippets

$(function() {
    var categories = $('[id^="category_"]');
    var category_buttons_a = $('.category_button a').each(function( idx ) {
        $(this).bind('click', function() {
            $(this).css({opacity:'1'});
            category_buttons_a.not(this).css({opacity:'0.4'});
            $('#blog-headers').css({backgroundPosition: '0 ' + (idx * -144) + 'px'});
            categories.hide().filter( '#category_' + (idx + 1) ).show();
        });
    });
});

Context

StackExchange Code Review Q#2900, answer score: 14

Revisions (0)

No revisions yet.