MrThunder
MrThunder

Reputation: 745

Is there a simpler to add multiple classes to different divs jquery

I am fading out a different divs on click for certain period of time at the moment I have a single function for each operation, I have named them .fade-a, .fade-b, .fade-c etc. Surely there must be a better way to do this as at the moment I just have along list that seems bloated.

Sorry if I am not explaining this very well I don't use much jQuery.

Thanks

$('.fade-a').click(function() {
    $('.fade-a').addClass('fade');
    var delay = setTimeout(function() {
        $(".fade-a").removeClass("fade");
    }, 1000)
});
$('.fade-b').click(function() {
    $('.fade-b').addClass('fade');
    var delay = setTimeout(function() {
        $(".fade-b").removeClass("fade");
    }, 1000)

});
$('.fade-c').click(function() {
    $('.fade-c').addClass('fade');
    var delay = setTimeout(function() {
        $(".fade-c").removeClass("fade");
    }, 1000)

});
$('.fade-d').click(function() {
    $('.fade-d').addClass('fade');
    var delay = setTimeout(function() {
        $(".fade-d").removeClass("fade");
    }, 1000)

});

HTML:

<div class="width33 site-top">
    <span>
        <img class="info-block-toggle-a fade-a site-overlay size-auto" src="images/i-am-the-cosmos.jpg" alt="" />
    </span>
</div>
<div class="width33 site-middle">
    <span>
        <img class="info-block-toggle-b fade-b site-overlay size-auto" src="images/dorje.jpg" alt="" />
    </span>
</div>
<div class="width33 site-bottom">
    <span>
        <img class="info-block-toggle fade-c site-overlay size-auto" src="images/harvey.png" alt="" />
    </span>
</div>

CSS:

.fade-a, .fade-b, .fade-c, .fade-d, .fade-e, .fade-f, .fade-g, .fade-h, .fade-i {
    -webkit-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1);
    -webkit-transition: all 0.5s ease-in;
    -moz-transition: all 0.5s ease-in;
    -ms-transition: all 0.5s ease-in;
    -o-transition: all 0.5s ease-in;
    transition: all 0.5s ease-in;
}
.fade-a.fade, .fade-b.fade, .fade-c.fade, .fade-d.fade, .fade-e.fade, .fade-f.fade, .fade-g.fade, .fade-h.fade, .fade-i.fade {
    -webkit-transform: scale(0);
    -ms-transform: scale(0);
    -o-transform: scale(0);
    transform: scale(0);
}

Upvotes: 0

Views: 82

Answers (2)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

Use the same class on all of them (e.g. fademe) and do this:

$('.fademe').click(function() {
    var $this = $(this);
    $this.addClass('fade');
    setTimeout(function() {
        $this.removeClass("fade");
    }, 1000)
});

Code snippet:

$('.fademe').click(function() {
  var $this = $(this);
  $this.addClass('fade');
  var delay = setTimeout(function() {
    $this.removeClass("fade");
  }, 1000)
});
.fade {
  border: 1px solid green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="width33 site-top">
  <span>
        <img class="info-block-toggle-a fademe site-overlay size-auto" src="https://via.placeholder.com/150/FF0000/FFFFFF?text=1" alt="" />
    </span>
</div>
<div class="width33 site-middle">
  <span>
        <img class="info-block-toggle-b fademe site-overlay size-auto" src="https://via.placeholder.com/150/00FF00/FFFFFF?text=1" alt="" />
    </span>
</div>
<div class="width33 site-bottom">
  <span>
        <img class="info-block-toggle fademe site-overlay size-auto" src="https://via.placeholder.com/150/0000FF/FFFFFF?text=1" alt="" />
    </span>
</div>

Notes:

  • Inside a click event, this is the DOM element clicked. $(this) is a jQuery object of the same element. You need to keep a reference to the original this, e.g. in a var, as the this inside the setTimeout callback is different.
  • Prefixing jQuery variable names with $ is just a common standard. Call it whatever you like :)
  • I used a green border to show your fade class as images were not available.

Upvotes: 5

Fagner Brack
Fagner Brack

Reputation: 2403

This enhances @TrueBlueAssie answer to comply with a more "simpler" way as requested by the OP. But "simpler" in this context represents a more meaningful and understandable code inside the click handler, trying to leverage more jquery and JS coolness.

I will be using .makeme -> .big classes, instead of .fademe -> .fade.

First lets go and use jquery queue inside each handler to handle proper execution:

$( ".makeme" ).on( "click", function( event ) {
  var $element = $( event.currentTarget );
  $({})
    .queue(function( next ) {
      $element.addClass( "big" );
      next();
    })
    .delay( 1000 )
    .queue(function( next ) {
      $element.removeClass( "big" );
      next();
    });
});

Link: http://jsfiddle.net/kxhpu4z6/

And that's it.

We can even play a little bit with a factory to create each queue callback that executes a single jQuery method and handles the next call for us:

// queueCallback by Fagner Brack (MIT Licensed)
// Create a callback for jquery queue mechanism that executes a single
// jquery method once resolved.
function queueCallback( element, method ) {
  var methodArgs = [].slice.call( arguments, 2 );
  var $element = $( element );
  return function( next )  {
    method.apply( $element, methodArgs );
    next();
  };
}

The click handler is now written like this:

$( ".makeme" ).on( "click", function( event ) {
  var element = event.currentTarget;
  $({})
    .queue( queueCallback( element, $.fn.addClass, "big" ) )
    .delay( 1000 )
    .queue( queueCallback( element, $.fn.removeClass, "big" ) );
});

Link: http://jsfiddle.net/kxhpu4z6/2/

The snippets can be modified to be adapted for each desired behavior after clicking in the element or after the 1s delay has ended.


EDIT: DO NOT USE THIS

I discovered custom queue using plain objects in jquery constructor was NEVER SUPPORTED.

It was never documented and plain object supported is being deprecated in jquery 3.0. So if you need a proper jquery queue you can use or create a custom plugin for that purpose and with a decent syntax.

Upvotes: 1

Related Questions