1

I know this is awfully simple, but I'm new to this and I just need to be shown it once. So when I'm using jQuery/javascript I find myself writing repetitive code again and again to target different elements with the same function, for example:

$(function() {
    $('.icon1').click(function() {
        $('.info1').toggle().addClass('animated fadeInDown');
        $('.info2, .info3, .info4').hide();
    });                        
});
$(function() {
    $('.icon2').click(function() {
        $('.info2').toggle().addClass('animated fadeInLeft');
        $('.info1, .info3, .info4').hide();
    });                      
});

and this repeats again for icon3 and icon4. I'm selecting a different element, showing another, hiding another three, and adding different classes in each function, and I don't know what would be the best way not to repeat the whole thing for each element. I would be very glad to be shown any ideas to refactor this, and wouldn't mind seeing how that is done in vanilla js also.
(For illustration the code here is a snippet from the code on the experience section of my portfolio where clicking on an icon reveals an info panel about it, and hides any previously shown info panels.)

4 Answers 4

2

Use a common class, use this, and not to remove it from the collection

$(function() {
    $('.commonClass').click(function() {
        $(this).toggle().addClass('animated fadeInDown');
        $('.commonClass').not(this).hide();
    });                        
});
Sign up to request clarification or add additional context in comments.

2 Comments

A follow up question, if I'm also changing the class I'm adding, do I have to rewrite this whole thing again for each class? So in my example, icon1 shows info1 with a fade down, while icon2 shows info2 with a fade left.
I created a common class for icons and info and tried to follow your example. but it doesn't work. $(function() { $('.icon').click(function() { $('.info').toggle(); $('.info').not(this).hide(); }); }); This just permanently keeps all info panels hidden. And if I select info1, info2 then I'm back to square one because each icon toggles a different info panel.
1

You should be able to separate those selectors with commas.

$('.icon1,.icon2').click(function()

Or assign each a single class they share that behavior? ".icon-btn" where you use ".icon-btn" as the selector for any you wish to have that behavior.

3 Comments

How do I make that work when each icon triggers a different info panel and hides another 3?
It'd probably be cleaner if you can assign a data-index="index" property on any clickable icons, then on icon click grab that index value and make modifications to the DOM from there. Using common classes with shared behaviors where you can would help so you can then just hide all with the common class then just show() the element that was clicked. An alternative could be to figure out the "ends with" selector $(name$="value") to .show() and .hide() with the .each() iterator on classes ending with specific digits? Best of luck!
Thanks a lot for this.
0

It would be better if you can plan your html better with data attribute for eg:

<div class="icon" data-info = "1"> <div>
<div class="icon" data-info = "2"> <div>

<div class="info-1 info"> <div>
<div class="info-2 info"> <div>
    $('.icon').click(function() {
    var className = '.info-' + $(this).data('info');
      $('.info').hide();
        $(className).toggle().addClass('animated fadeInDown');

    });    

you can also remove .info1,.info2 from js code by adding some common class in html as info to them. for eg

4 Comments

Whoa! That was an amazing insight. The only problem with this one was that the infopanels didn´t toggle show/hide. But I added @espascarello 's idea not() and it worked like a charm: $('.icon').click(function(){ var infoPanel = '.info-' + $(this).data('info'); $('.info').not(infoPanel).hide(); $(infoPanel).toggle(); }); Here's the working example link
And now I wonder, if i want to take this and add different classes to different icons instead of fadeInDown for all, is there an elegant way I could go about doing this without repeating the same block of code?
I have answered my own question by trying out an if statement and it works fine if($(this).data('info') === 1 || $(this).data('info') === 4 ){ $(infoPanel).addClass('test'); } else { $(infoPanel).addClass('test2'); } My question now, is if I want a different class added to each one of the icons, do I just add else ifstatements or is there a more concise way of doing it?
you can generate new classes based on same approach. var animateClass = '.test-' + $(this).data('info'); now you can add as $('infopanel').addClass(animateClass).
0

I'm making some assumptions about your actual HTML, but you could probably leverage the siblings() method in this case.

$(document).on('click', '.icon', function() {

  $(this).toggle().addClass('animated fadeIn')
         .siblings().hide();

});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.