pmerino
pmerino

Reputation: 6130

How can I do this jQuery code in a more reduced way?

I have the following jQuery code:

$('#menu .selected').removeClass('selected');
      $('#homel').addClass('selected');
      $('#home').slideDown(150, function() {
        $('#public').slideUp(200);
        $('#login').slideUp(200);
        $('#faq').slideUp(200);

      });

Which, as you can guess, hides and shows div boxes. In that example #homel is the Home link, and #home is the home div. This looks ok, but if I want to add a new box, for example, #registerI have to add here and on every other box code (#public, #login and #faq) the code: $('#register').slideUp(200); Is there any way that can be simplified and made generic for all?

EDIT: jsFiddle link for the example here

Upvotes: 0

Views: 66

Answers (3)

Emre Erkan
Emre Erkan

Reputation: 8482

Here is a different solution. I gave all h3 divs a common class and select them with one selector. This way it's you don't have to change your code everytime you add another div. There is also a function for slideUp. Now all routes can use same function, no need for lots of anonymous functions.

This is the final result;

HTML

<div id="menu">
    <a href="./#/home" class="selected" id="homel">Home</a> <a href="./#/public" id="publicl">Public</a> <a href="./#/users/login" id="loginl">Login</a> <a href="./#/faq" id="faql">FAQ</a>
</div>
<div id="content">
    <div id="home" class="h3div">
        <h3>Welcome</h3>
    </div>
    <div id="public"class="h3div">
        <h3>Public</h3>
    </div>
    <div id="login"class="h3div">
        <h3>Login</h3>
    </div>
    <div id="register"class="h3div">
        <h3>Register</h3>
    </div>
    <div id="faq" class="h3div">
        <h3>Frequently Asked Questions</h3>
    </div>
</div>

Javascript

$(document).ready(function() {
    $.routes({
        '/': function() {
            $('#home').slideDown(200);
        },
        '/home': function() {
            menuSlideUpDown('home');
        },
        '/public': function() {
            menuSlideUpDown('public');
        },
        '/users/:what': function(params) {
            if (params.what == "login") {
                menuSlideUpDown('login');
            } else if (params.what == "register") {
                menuSlideUpDown('login');
            }
        },
        '/faq': function() {
            menuSlideUpDown('faq');
        }
    });
});

function menuSlideUpDown(item) {
    $('#menu a').removeClass('selected').filter('#' + item + 'l').addClass('selected');
    $('#' + item).slideDown(150, function() {
        $('.h3div').not(this).slideUp(150);
    });
}

And working example of final result is here.

Upvotes: 0

kba
kba

Reputation: 19466

Moving everything into a function will shorten your code significantly.

function collapse(e)
{
    $('#menu .selected').removeClass('selected');
      $('#'+e+'l').addClass('selected');
      $('#'+e).slideDown(150, function() {
        e=='public' || $('#public').slideUp(200);
        e=='login' || $('#login').slideUp(200);
        e=='faq' || $('#faq').slideUp(200);
        e=='home' || $('#home').slideUp(200);
      });
}
$(document).ready(function(){
  $.routes({
    '/': function(){
      $('#home').slideDown(200);
    },
    '/home': function(){ collapse('home'); },
    '/public': function() { collapse('public'); },
    '/users/:what':function(params) {
      if(params.what == "login" || params.what == "register")
        collapse('login');
    },
    '/faq':function() { collapse('faq'); },
  });

});

Upvotes: 0

Pointy
Pointy

Reputation: 413737

Well you could give those three things a class and use that to operate on them (the "public", "login", and "faq" elements), or:

$('#public, #login, #faq').slideUp(200);

If you gave those things a class then you'd just say

$('.slideMeUp').slideUp(200);

or whatever. If you only want to affect those inside the outer container:

$('#home').slideDown(300, function() {
  $(this).find('.slideMeUp').slideUp(200);
});

edit — ah OK well now that I look at your markup I see what the deal is. In a case like that, personally I'd use a "data-" attribute to relate the <a> elements in the menu to the page sections that they're supposed to control. To do that, the menu tags would look like this:

<a href="./#/home" class="menu-item selected" id="homel" data-section='home'>Home</a>

The page sections should also have a class:

    <div id="home" class='menu-section'>
        <h3>Welcome</h3>
    </div>

Now, I'm not familiar with how that "routes" plugin works, but that should make it a lot easier to control things. If you have a reference to one of the menu tags, then you can get the "id" value for the page section it controls with:

    var sectionId = $(menuItem).data('section');

Then you can remove class "selected" from all the ".menu-section" divs, add "selected" to the newly-selected one, and then slide all the others up:

    $('.content .menu-section:not(.selected)').slideUp(200);

Upvotes: 4

Related Questions