How can I confirm that all elements have been properly reset to their original positions prior to making any further adjustments to them?

In need of some creative brainstorming, I'm working on a website design featuring ten overlapping cards. When the mouse hovers over a card, it expands while others move away. My goal is for each card to return to its original position once the cursor moves off it. Here's the HTML code snippet:

Exploring solutions, I attempted using onMouseOver and onMouseOut in HTML but hit roadblocks. Similarly, my trials with GSAP's timeline animation proved challenging to control.

The current setup involves adding and removing event listeners with timeouts to regulate function calls' speed.

var cards = document.getElementsByClassName('card');
var currentCard;
var currentIndex;
var leftSpread = 150;
var rightSpread = 200;
var initialOffset = 100;

(function initialLoad() {
  for (var i = 0; i < cards.length; i++) {
    cards[i].style.zIndex = i;

    cards[i].addEventListener("mouseenter", this);

    if (i > 0) {
      cards[i].style.left = cards[i - 1].offsetLeft + initialOffset + 'px';
    }
  }
})();

function handleEvent(evt) {
  switch (evt.type) {
    case "mouseenter":
      this.cardMouseOver(evt);
      break;
    case "mouseout":
      this.cardMouseOut(evt);
      break;
    default:
      return;
  }
}

function cardMouseOver(event) {
  currentIndex = event.target.style.zIndex;
  event.target.style.zIndex = 10;

  for (var i = 0; i < cards.length; i++) {
    if (event.target == cards[i]) {
      currentCard = i;
    } else {
      cards[i].removeEventListener("mouseenter", this);
    }
  }

  setTimeout(function() {
    cards[currentCard].addEventListener("mouseout", this);
  }, 50);

  for (var i = 0; i < cards.length; i++) {
    if (i < currentCard) {
      cards[i].style.left = cards[i].offsetLeft - leftSpread + 'px';
    } else if (i > currentCard) {
      cards[i].style.left = cards[i].offsetLeft + rightSpread + 'px';
    }
  }

  cards[currentCard].removeEventListener("mouseenter", this);
}

function cardMouseOut(event) {
  cards[currentCard].style.zIndex = currentIndex;

  setTimeout(function() {
    for (var i = 0; i < cards.length; i++) {
      cards[i].addEventListener("mouseenter", this);
    }
  }, 100);

  for (var i = 0; i < cards.length; i++) {
    if (i === currentCard) {
      cards[i].removeEventListener("mouseout", this);
    }
  }

  for (var i = 0; i < cards.length; i++) {
    if (i < currentCard) {
      cards[i].style.left = cards[i].offsetLeft + leftSpread + 'px';
    } else if (i > currentCard) {
      cards[i].style.left = cards[i].offsetLeft - rightSpread + 'px';
    }
  }
}
body {
  background-color: #242424;
  padding: 0;
  margin: 0;
}

.cards-container {
  background: #fff;
  margin: 20px auto;
  position: absolute;
  left: 21%;
  top: 375px;
}

.card {
  position: absolute;
  background: rgb(255, 255, 255);
  border: 1px solid black;
  height: 250px;
  transition: 0.2s;
  width: 200px;
  box-shadow: -1px 0px 1px 1px rgba(0, 0, 0, 0.747);
}

.card:hover {
  transition: all 0.2s ease;
  width: 250px;
  height: 350px;
  top: -75px;
}
<body>
  <header>
    <div class="cards-container">
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
    </div>
  </header>
</body>

<script type="text/javascript" src="http://code.jquery.com/jquery-3.4.0.min.js"></script>

My aim is to achieve smooth transitions based on the highlighted card and reset positions when no card is highlighted.

Answer №1

There are a few different approaches you could take to accomplish this task

  1. An option is to use a boolean flag that switches when an element is in motion or out of place. Once the element returns to its original position, you can switch it back.
let hasDOMChanged = false

function handleEvent(event) {
  hasDOMChanged = true
  switch (event.type) {
    case "mouseenter":
      this.handleMouseEnter(event);
      break;
    case "mouseout":
      this.handleMouseOut(event);
      break;
    default:
      return;
  }
}

// Add a function to reset hasDOMChanged to false when the element is restored
  1. Another approach is to manage animations and CSS modifications using classes (.inUse, .active, .hovered, etc.) and then create a loop that verifies if any element possesses an "active" class
const pageModified = () => {
  if(Array.from(document.querySelectorAll(".inUse")).length > 0) {
    return false
  } else {
    return true
  }
}

UPDATE: In relation to animations, they become quite simple once you understand the process! I suggest checking out W3Schools' guide on @keyframes

https://www.w3schools.com/cssref/css3_pr_animation-keyframes.asp

You can also specify animation-direction as forward, reverse, etc. It offers great versatility!

Answer №2

After some persistent digging, I stumbled upon the solution which turned out to be much simpler than anticipated. To achieve a smooth animation when hovering over cards with the mouse, I utilized CSS transition and transform attributes.

I defined the following CSS classes:

.card {
    position: absolute;
    background: rgb(255, 255, 255);
    height: 275px;
    width: 200px;
    box-shadow: -1px 0px 3px 1px rgba(0, 0, 0, 0.747);
    transition: all .4s ease;
}

.card.left {
    transform: translateX(-175px);
}

.card.right {
    transform: translateX(175px);
}

To achieve the desired effect, I added and removed event listeners for "mouseenter" and "mouseover."

function handleEvent(evt) {
    switch(evt.type) {
        case "mouseenter":
            this.cardMouseOver(evt);
            break;
        case "mouseout":
            this.cardMouseOut(evt);
            break;
        default:
            return;
    }
}

function cardMouseOver(event) {
    for (var i = 0; i < cards.length; i++) {
        if (event.target == cards[i]) {
            currentCard = i;
        }
    }

    // Code snippet continued...
}

function cardMouseOut(event) {
    // Code snippet continued...
}

In this script, cards represents an array of the "card" elements.

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

Execution priority of Javascript and PHP in various browsers

I implemented a basic JavaScript function to prevent users from using special characters in the login form on my website: $("#login_button").click(function(){ formChecker(); }); function formChecker() { var checkLogin = docum ...

Tips on efficiently rebinding jQuery events to dynamically loaded content without having to manually do it for each event or class

Recently, I encountered an issue with my jQuery app where I needed to bind different functions to elements within one div dynamically. Specifically, I had a "delete-function" attached to all ".btn-delete" elements and an "add-function" linked to all ".btn- ...

Configuration of an MVC-based web application

As a newcomer to web application development, I am currently working on building a web application using the Model-View-Controller pattern. My setup includes a MySQL database for the Model, JSP pages for the Views, and a DAO for the Controller. I am looki ...

A quick guide on automatically populating text boxes with characteristics of the item chosen from a drop-down menu

On my webpage, I am looking to automatically populate textboxes with information (such as common name, location, etc.) of the selected shop from a dropdown list without having to refresh the page. Here is the dropdown list: <select id="shops" class="f ...

Combine an array of objects that are dynamically created into a single object

Having trouble transforming the JSON below into the desired JSON format using JavaScript. Current JSON: { "furniture": { "matter": [ { "matter1": "Matter 1 value" }, { "matter2": "Matter 2 value" }, { ...

"Notification: The marker element has been eliminated" encountered while attempting to restore text ranges using Rangy within a Vue component

I have a rather intricate Vue component that includes a contenteditable div. My goal is to highlight words within this div using the Rangy library and add extra markup while retaining this markup even after editing the text. Initially, I planned on asking ...

"Applying CSS styles to expand the size of

Is there a way to prevent the blue div from overflowing the red div, but still always fill its parent container? I searched on stackoverflow and found suggestions to use height: 100%, but this causes issues when the child element has padding. How can this ...

Place the div directly beside the input field on the right side

I am attempting to align a div directly beside the text being entered in a text input field. It seems logical to me that this could be achieved by measuring the length of the input value and positioning the div accordingly. However, the issue I am facing i ...

How can I adjust the Bootstrap container width without it changing when resizing the browser window?

As I work on developing my website, I am utilizing Twitter's bootstrap grid system. Despite my efforts, I have been unable to find a solution for fixing the width of the site. My goal is to lock the size in place so that it remains constant regardless ...

in node.js, virtual machine scripts can import modules using the require function

I am currently developing a command-line interface using node.js that runs an external script > myapp build "path/to/script.js" myapp is a node.js application that executes the script provided as a command-line argument. In simple terms, it performs ...

Update all occurrences of a particular value to null within the Realtime Database using Firebase Cloud Functions

I need to update the values of a specific userID linked to multiple post keys in my database by setting the userID to null. The userIDs are associated with post keys located in the path: posts/ivies/userIDs in my database. Take a look at how the database i ...

Issues with the functionality of the WordPress plugin

The issue with Spin360: All scripts are linked in functions.php add_action('wp_footer', 'add_scripts'); function add_scripts() { if(is_admin()) return false; wp_deregister_script('jquery'); wp_enqueue_script ...

Updating a value in Expressjs variable is not working as expected

In the code snippet below, I have declared a variable called sumOfRevenue. I assigned it a value of 10 in the router, but when I try to print its value, it comes out blank. Can you please help me understand why it's not showing as 10? Please review t ...

Array updating using the foreach method in Angular

Hey everyone, I've encountered an error that seems to be related to scope and I could use some advice. I'm currently looping through an array and trying to push the results to another array. However, when I attempt to push the results to public m ...

The best way to organize and position a Label and TextBox in C#

I need help styling the aspx file. The Label and TextBox elements are not aligned properly. I want the Label and TextBox to be positioned side by side with appropriate spacing. <div class="col-md-12"> <p> ...

Doubt surrounding the behavior of Node.js when a file is required that does not export anything from a module

My understanding of Node.js' require() function and module.exports is high-level, but I still find some behaviors confusing. Imagine I have two simple one-line files named a.js and b.js. In a.js: require('./b.js'); and in b.js: console. ...

Tips for hiding a bootstrap modal in Angular4 when it has no content

I am currently working on an Angular 4 e-commerce application. One of the requirements is to hide a bootstrap modal when there are no products in the cart. When a user selects some products, they are added to the mycart modal screen. The user also has the ...

Utilize AJAX to dynamically refresh the page without having to reload it, enabling the use of both POST and GET methods

In order to avoid reloading the page when refreshing, I am utilizing Ajax for this particular 3-sided content along with JavaScript. Here is the code: Content: <ul id="nav"> <li><a href="ajax_adat.php?id=8&epul=0">Data</a>< ...

Using Jquery to iterate through a dynamic list of elements

Currently, I am exploring the idea of creating a forEach loop that can handle an unspecified number of elements. The goal is to randomly select one element, perform XYZ actions on it, make it visible, and then eliminate it from consideration. This process ...

Utilize the power of DOJO JavaScript to implement Reverse AJAX functionality in

Exploring the possibility of implementing Reverse AJAX with the DOJO Javascript framework. Curious if DOJO has built-in support for this feature like other frameworks such as DWR. I am currently working with the most recent version of DOJO - any guidance ...