Brian
Brian

Reputation: 297

How to limit class animations to clicked elements and their content

I know this question has been asked and answered, but here is a slightly more complicated situation. I have a list of cards, all set to animate once clicked. Of course the animation is created by using the toggleClass() command and the initial problem was that if i Clicked one card, all of them animated. This was easily fixed by using the $(this) statement. However, I then decided to add content to the cards, that would display only once the card is clicked. I thought this would be affected by the $(this) statement too, but it is not and now when I click a card, that card animates but the content of other cards is displayed too.

$(".card").click(function() {
  $(this).toggleClass("transform-active");
  $(".disappear").toggleClass("appear");
});
/* CARDS SECTION */

.cards {
  display: block;
  position: absolute;
  width: 100%;
  top: 60px;
  list-style: none;
  text-decoration: none;
  z-index: -1;
}

.cards li {
  display: block;
  position: relative;
  width: 100%;
  padding-bottom: 10px;
}

.card {
  position: relative;
  background-color: #ffffff;
  height: 150px;
  width: 100%;
  left: -5%;
  border-radius: 8px;
  box-shadow: 2px 2px 2px #686868;
  cursor: pointer;
}


/* CARDS CONTENT SECTION */

#containText {
  position: absolute;
  width: 76%;
  color: #58a7dd;
  top: -2px;
  left: 90px;
  text-align: justify;
}

#containText p {
  position: absolute;
  top: 30px;
}

.face {
  position: relative;
  height: 70px;
  width: 70px;
  top: 10px;
  left: 10px;
  border: solid #58a7dd;
  background-color: white;
  border-radius: 50%;
  color: #58a7dd;
}

.face h2 {
  position: relative;
  left: 3px;
  top: 20px;
  transform: rotate(90deg);
}

.extra {
  position: relative;
  width: 90%;
  top: 7px;
  margin: auto;
  color: #2f4f4f;
}

.disappear {
  position: relative;
  width: 90%;
  height: 40%;
  top: 5px;
  margin: auto;
  color: #2f4f4f;
  opacity: 0;
}

.appear {
  animation: appear 1.2s ease;
  animation-fill-mode: forwards;
}

@keyframes appear {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.transform {
  -webkit-transition: all 0.2s ease;
  -moz-transition: all 0.2s ease;
  -o-transition: all 0.2s ease;
  -ms-transition: all 0.2s ease;
  transition: all 0.2s ease;
}

.transform-active {
  background-color: #ffffff;
  height: 300px;
  width: 100%;
  box-shadow: 6px 6px 6px #888888;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="cardList" class="cards">
  <li>
    <div class="card transform">
      <div class="face">
        <h2>: )</h2>
      </div>
      <div id="containText">
        <h3>HI! I am a card.</h3><br>
        <p>Click me to trigger the animation.</p>
      </div>
      <div class="extra">
        <p>Here is some extra info about the items on this card, such as stuff, things and blah.</p>
      </div>
      <div class="disappear">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
      </div>
    </div>
  </li>
  <li>
    <div class="card transform">TWO</div>
  </li>
  <li>
    <div class="card transform">THREE</div>
  </li>
  <li>
    <div class="card transform">FOUR</div>
  </li>
  <li>
    <div class="card transform">FIVE</div>
  </li>
  <li>
    <div class="card transform">SIX</div>
  </li>
</ul>

CodePen with working example: https://codepen.io/BGGrieco/pen/PjOevR

Upvotes: 0

Views: 48

Answers (3)

Tejasvi Karne
Tejasvi Karne

Reputation: 648

That is because you are asking all the .disappear elements to .appear.

$(".disappear").toggleClass("appear");

You are not specifying in any way that you want the div.disappear within this to toggleClass('appear').

Try this instead:

$(this).children('.disappear').toggleClass('appear');

Upvotes: 2

williamli
williamli

Reputation: 4122

Try changing your JS to the following:

$(".card").click(function()
{
  $(this).toggleClass("transform-active");
  $(".disappear", this).toggleClass("appear");
});

Your problem was that you were toggling the 'appear' class of ALL elements with the class 'disappear', which covers the content of all the cards, including those that are not active.

Adding , this to the select statement of jQuery will limit the context of 'disappear' to the scope of this. (See http://api.jquery.com/jquery/#jQuery1)

Here is the modified CodePen: https://codepen.io/williamli/pen/LLBPOv

$(".card").click(function()
{
  $(this).toggleClass("transform-active");
  $(".disappear", this).toggleClass("appear");
});
body
{
  position: relative;
  background-color: #f9f9f9;
  font-family: "arial";
  margin: 0;
  padding: 0;
}

.header p
{
  text-align: center;
  font-weight: lighter;
  font-size: 20px;
  line-height: 12px;
  color: white;
}

/* APP BARS SECTION */
.header
{
  position: fixed;
  top: 0%;
  width: 100%;
  height: 50px;
  background-color: #d36363;
  box-shadow: 0px 6px 6px #888888;
  z-index: +1;
}

.footer
{
  position: fixed;
  bottom: 0%;
  width: 100%;
  height: 50px;
  background-color: #d36363;
  box-shadow: 0px -6px 6px #888888;
}

/* CARDS SECTION */
.cards
{
  display: block;
  position: absolute;
  width: 100%;
  top: 60px;
  list-style: none;
  text-decoration: none;
  z-index: -1;
}

.cards li
{
  display: block;
  position: relative;
  width: 100%;
  padding-bottom: 10px;
}

.card
{
  position: relative;
  background-color: #ffffff;
  height: 150px;
  width: 100%;
  left: -5%;
  border-radius: 8px;
  box-shadow: 2px 2px 2px #686868;
  cursor: pointer;
}

/* CARDS CONTENT SECTION */
#containText
{
  position: absolute;
  width: 76%;
  color: #58a7dd;
  top: -2px;
  left: 90px;
  text-align: justify;
}

#containText p
{
  position: absolute;
  top: 30px;
}

.face
{
  position: relative;
  height: 70px;
  width: 70px;
  top: 10px;
  left: 10px;
  border: solid #58a7dd;
  background-color: white;
  border-radius: 50%;
  color: #58a7dd;
}

.face h2
{
  position: relative;
  left: 3px;
  top: 20px;
  transform: rotate(90deg);
}

.extra
{
  position: relative;
  width: 90%;
  top: 7px;
  margin: auto;
  color: #2f4f4f;
}

.disappear
{
  position: relative;
  width: 90%;
  height: 40%;
  top: 5px;
  margin: auto;
  color: #2f4f4f;
  opacity: 0;
}

.appear
{
  animation: appear 1.2s ease;
  animation-fill-mode: forwards;
}

@keyframes appear
{
  0%
  {
    opacity: 0;
  }
  100%
  {
    opacity: 1;
  }
}

.transform
{
  -webkit-transition: all 0.2s ease;
  -moz-transition: all 0.2s ease;
  -o-transition: all 0.2s ease;
  -ms-transition: all 0.2s ease;
  transition: all 0.2s ease;
}

.transform-active
{
  background-color: #ffffff;
  height: 300px;
  width: 100%;
  box-shadow: 6px 6px 6px #888888;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="styling.css" type="text/css">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  </head>
  <body>
    <!--HEADER-->
    <div class="header">
      <div id="info">
        <p>Current Page</p>
      </div>
    </div>

    <!--CARDS-->
    <ul id="cardList" class="cards">
      <li><div class="card transform">
        <div class="face"><h2>: )</h2></div>
          <div id="containText">
            <h3>HI! I am a card.</h3><br>
            <p>Click me to trigger the animation.</p>
          </div>
          <div class="extra">
            <p>Here is some extra info about the items on this card, such as stuff,                    things and blah.</p>
          </div>
          <div class="disappear">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod                tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim                    veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea                commodo consequat.</p>
          </div>
          </div>
      </li>
      <li><div class="card transform">TWO
        <div class="extra">
            <p>Here is some extra info about the items on this card, such as stuff,                    things and blah.</p>
          </div>
          <div class="disappear">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod                tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim                    veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea                commodo consequat.</p>
          </div>
        </div></li>
      <li><div class="card transform">THREE</div></li>
      <li><div class="card transform">FOUR</div></li>
      <li><div class="card transform">FIVE</div></li>
      <li><div class="card transform">SIX</div></li>
    </ul>

    <!--FOOTER-->
    <div class="footer"></div>
  </body>

Upvotes: 1

DavidDomain
DavidDomain

Reputation: 15293

You need to change:

$(".card").click(function() {
  $(this).toggleClass("transform-active");
  $(".disappear").toggleClass("appear");
});

to:

$(".card").click(function()
{
  $(this).toggleClass("transform-active");
  $(this).find(".disappear").toggleClass("appear");
});

That way you will only target the <div> element with a class of .disappear in the current clicked element.

$(".card").click(function() {
  $(this).toggleClass("transform-active");
  $(this).find(".disappear").toggleClass("appear");
});
.cards
{

  margin: 0;
  padding: 0;
  list-style: none;
  text-decoration: none;
}

.cards li
{
  width: 100%;
  padding-bottom: 10px;
}

.card
{
  background-color: #ffffff;
  height: 150px;
  width: 100%;
  padding: 6px 12px;
  border-radius: 8px;
  box-shadow: 2px 2px 2px #686868;
  cursor: pointer;
}

/* CARDS CONTENT SECTION */
#containText
{
  position: absolute;
  width: 76%;
  color: #58a7dd;
  top: -2px;
  left: 120px;
  text-align: justify;
}

#containText p
{
  position: absolute;
  top: 30px;
}

.face
{
  height: 70px;
  width: 70px;
  border: solid #58a7dd;
  background-color: white;
  border-radius: 50%;
  color: #58a7dd;
}

.face h2
{
  position: relative;
  left: 3px;
  top: 20px;
  transform: rotate(90deg);
}

.extra
{
  position: relative;
  width: 90%;
  top: 7px;
  margin: auto;
  color: #2f4f4f;
}

.disappear
{
  position: relative;
  width: 90%;
  height: 40%;
  top: 5px;
  margin: auto;
  color: #2f4f4f;
  opacity: 0;
}

.appear
{
  animation: appear 1.2s ease;
  animation-fill-mode: forwards;
}

@keyframes appear
{
  0%
  {
    opacity: 0;
  }
  100%
  {
    opacity: 1;
  }
}

.transform
{
  -webkit-transition: all 0.2s ease;
  -moz-transition: all 0.2s ease;
  -o-transition: all 0.2s ease;
  -ms-transition: all 0.2s ease;
  transition: all 0.2s ease;
}

.transform-active
{
  background-color: #ffffff;
  height: 300px;
  width: 100%;
  box-shadow: 6px 6px 6px #888888;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="cardList" class="cards">
    <li><div class="card transform">
      <div class="face"><h2>: )</h2></div>
        <div id="containText">
          <h3>HI! I am a card.</h3><br>
          <p>Click me to trigger the animation.</p>
        </div>
        <div class="extra">
          <p>Here is some extra info about the items on this card, such as stuff,                    things and blah.</p>
        </div>
        <div class="disappear">
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod                tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim                    veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea                commodo consequat.</p>
        </div>
        </div>
    </li>
    <li><div class="card transform">TWO</div></li>
    <li><div class="card transform">THREE</div></li>
    <li><div class="card transform">FOUR</div></li>
    <li><div class="card transform">FIVE</div></li>
    <li><div class="card transform">SIX</div></li>
  </ul>

Upvotes: 1

Related Questions