Search code examples
jqueryclasstoggleclass

Toggle other specific classes off when toggling one on


I have a set of div elements that are not children of one another and each have individual background images, and therefore use individual class names.

When clicking on one I want it to highlight by swapping its background image. If another div is highlighted I want to un-highlight it by swapping its background image back. If the same highlighted div is clicked I want to un-highlight it.

My current method is to do this via toggleClass and I've managed to swap the class of a div I've clicked on, but not to swap the others back.

I've managed this before with div elements that all swap to the same class by using the .not feature, but I'm struggling to do this with div elements that use individual, specific classes.

JSFiddle version here: https://jsfiddle.net/el_simmo/8cnu776j/3/

$(document).ready(function(){
    var theboxes = $("#svg1 #svg2 #svg3");
    var clickclasses = $("svg1classclick svg2classclick svg3classclick");

    $("[id^='svg']").on("click", function(){
        var thissvg = $(this);
        var svgclick = $(this).attr("id") + "classclick";
        thissvg.toggleClass(svgclick);
        theboxes.not(thissvg).removeClass(clickclasses);
    });
});

Solution

  • You can massively improve your logic and DRY up your code with the use of common classes. Firstly, apply a common class to all the div elements you want to be clickable, in my example I user svgContainer:

    <div>
        <div id="svg1" class="svgContainer"></div>
    </div>
    <div>
        <div id="svg2" class="svgContainer"></div>
    </div>
    <div>
        <div id="svg3" class="svgContainer"></div>
    </div>
    

    From there you can use the following much simpler logic to toggle the highlight on and off with a single highlight class:

    $(".svgContainer").on("click", function () {
        $(this).toggleClass('highlight');
        $('.svgContainer').not(this).removeClass('highlight');
    });
    
    .svgContainer { 
        height: 60px;
        background-repeat: no-repeat;
    }
    #svg1 {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/teacher.svg");
    }
    #svg1.highlight {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/teacher-purple.svg");
    }
    #svg2 {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/student.svg");
    }
    #svg2.highlight {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/student-purple.svg");
    }
    #svg3 {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/support.svg");
    }
    #svg3.highlight {
        background-image: url("http://fdslive.oup.com/www.oup.com/elt/general_content/global/measuring_impact/images/svgs/support-purple.svg");
    }
    

    Working fiddle

    Note the use of compound class selectors in the CSS means you only need to toggle a single class, which makes the JS code a lot simpler.