Disabling animation state when a different div is clicked

I've created a card set with CSS animations triggered by clicking on the cards. While I'm satisfied with the outcome, there is an issue I need help with: when I click on a card, it animates and reveals additional content. Clicking on the same card again reverts it to its original state. However, if I click on one card and then another without closing the first one, both cards remain animated. How can I implement a solution where clicking on one card causes all other cards to return to their un-animated state?

<html>
  <head>
    <meta charset="UTF-8">
    <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></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>

CSS:

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;
}

jQuery:

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

View the working demo here: https://codepen.io/BGGrieco/pen/PjOevR

Answer №1

To easily achieve this effect, you can save the previous element and then hide it when a new one is clicked:

let previousElement;

$(".card").click(function(){
  if(previousElement) 
     $(previousElement).removeClass("transform-active");

  if(previousElement !== this) 
     $(this).addClass("transform-active");

  previousElement = this;
});

Answer №2

Here's a thought: How about looping through all elements with the "card" class, resetting their current class before assigning a new one to the clicked card?

$(".card").click(function()
{
  // Reset all cards
  $(".card").each(function(){
     $(this).removeClass("transform-active");
     $(this).addClass("transform");

     // Also reset their children with the "appear" class
     $(this).children(".appear).each(function(){
       $(this).removeClass("appear");
       $(this).addClass("disappear");
     }
  });

  // Set "transform-active" for the clicked card ...
  $(this).addClass("transform-active");
  $(this).removeClass("transform");

  // ... and do the same for its children with the "disappear" class
  $(this).children(".disappear).each(function(){
     $(this).addClass("appear");
     $(this).removeClass("disappear");
  }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Automatically adjusting the size of two divs with an unspecified width

Is it possible for the DIVs to resize based on the size of the nested image? That's what I'm trying to accomplish. Within a main div, I have two nested DIVs - one with an image to the right and the other with text to the left. I want these DIVs ...

Initiate CSS-Transitions using JavaScript

Despite reading 5 tutorials on how to initiate a CSS-Transition with JavaScript, I am unable to get it to work properly. My current browser is Safari. Below is the code that I have been working on: <html> <head> <title>Test</title&g ...

What is the best way to build a personalized discussion platform: employing tables, <ul> <li>, <dl> <dt>, or div elements?

Looking to create flexible columns and rows with borders on the left and right of each column. If one row in a column stretches more, the other columns in that row should also stretch accordingly. Came across liquid 2 column layouts and 3 column layouts, b ...

Tips for minimizing the gap between two rows in a table with a set height

I've created a table, but I'm facing an issue where the space between two elements is too large when there are multiple items in the loop. How can I decrease the spacing between these elements? <table width="100%" height="280" border="1" st ...

The caching mechanism in IE 11 is preventing Ajax from loading and displaying data

Utilizing Ajax to verify data and display it on the page, alongside implementing varnish cache. The data appears correctly on all web browsers, with the exception of IE 11, unless the varnish cache is disabled. function checkMyData() { var surl = 'in ...

"Enjoy a unique browsing experience with a two-panel layout featuring a fixed right panel that appears after scrolling

I am facing difficulty in designing a layout with two panels where the left panel has relative positioning and the right panel becomes fixed only after a specific scroll point. Additionally, I need the height of the right panel to adjust when the page scro ...

Having difficulty parsing or assigning JSON response: The response is being interpreted as [object Object]

Working with the Flickr API, Javascript/JQuery, and AJAX, I have the following code: function getRequest(arguments) { var requestinfo; $.ajax({ type: 'GET', url: flickrurl + '&'+ ...

Finding alternative solutions without using the find() method when working with Angular

How can I use an equivalent to find(".class") in AngularJS? I came across this solution: //find('.classname'), assumes you already have the starting elem to search from angular.element(elem.querySelector('.classname')) I attempted to ...

Run a targeted command on AWS Beanstalk

I have a unique node.js application that specifically functions with sqlite. I am interested in conducting a 'proof of concept' on AWS ElasticBeanstalk without the need to adjust the node.js app to be compatible with a supported database Prior ...

Sign in with AJAX in codeigniter framework

I am currently working on implementing AJAX functionality into my project. I aim to enable user login upon clicking the login button. Below, you will find the relevant code snippets. The view is invoking the login function in my controller. View <form ...

Working with Python and BeautifulSoup to retrieve <td> elements in a table without specified IDs or classes on HTML/CSS documents

While utilizing Selenium, Python, and Beautiful Soup to scrape a web page, I encountered the challenge of outputting table rows as comma-separated values due to the messy structure of the HTML. Despite successfully extracting two columns using their elemen ...

Tips for extracting information from a JQuery getJSON callback

I'm struggling to figure out how to extract the JSON object data from the callback function and process it later on the page instead of within the callback itself. I haven't found any clear instructions on how to do this, so I'm reaching out ...

Tips for accurately specifying types for TypeScript map, reduce, filter, and other functions

Encountering errors in my TS code when attempting to provide the correct type to the built-in .map and .filter functions. For example, using: Object.values(league.games).map((game: Game) => { results in Error: Argument of type '(game: Game) => ...

The encoding of Node.js using npm

Looking to install the validate .json file below using npm: { "name": "node-todo", "version": "0.0.0", "description": "Simple todo application", "main": "server.js", "dependencies": { "express": "~3.4.4", "mongoose": "~ ...

How can I line up columns in an HTML table?

I am facing a challenge while trying to set up a basic form with a table in the initial stages of my Angular project. I have been struggling to get the columns to align properly. Despite numerous attempts with various styling options for HTML <table> ...

What is the easiest way to create a dropdown form/menu with clickable links?

Looking to create a simple dropdown form for site links in either HTML, Java, or PHP. Want the selected option to open a new link in the browser without using a submit button. I've included what I have so far below, but need help with values and corre ...

Parallax effect overlay for DIV

Planning to give my website a makeover and I'm thinking of adding some parallax effects to make it more engaging. My idea is to have 3 boxes overlapping each other (with the 2nd and 3rd box appearing blurry). These boxes would be placed at the top of ...

View the edited image preview instantly upon selecting the image

I have selected an image and previewed it before submitting the form. However, now I wish to be able to edit the file immediately after selecting it, preview the changes, and then submit the file. <input type ="file" accept="image/*" id="image" name="i ...

Error being thrown in Express/Mongoose not being caught and handled

While using Postman to test my APIs, I'm encountering an issue with mongoose. It seems that when I use throw new Error() within the userSchema, the error does not get caught by the route.post. How can I ensure that errors thrown using throw new Er ...

Question about loading jQuery

I have implemented a jQuery load function to scroll between pages of a calendar on my website. Here is the code snippet I'm using: $(document).ready(function(){ $('a.cal').bind('click', function(e) { var url ...