Using jQuery to show/hide linked CSS3 animations upon Mouseenter/Mouseleave events

Exploring the capabilities of animate.css and jQuery within a bootstrap environment has been quite interesting for me. However, I've encountered a major issue!

I am attempting to trigger animations on mouseenter / mouseleave, which led me to create a series of complex chained callbacks that are now causing me frustration.

Take a look at my jQuery code (using no-conflict mode due to other plugins):

jQuery(document).ready(function () {

    var animationend = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
    var imgRotacion = "animated rotateOut";
    var h3Bounce = "animated bounceIn";
    var pFlip = "animated flipInX";
    var imgRotacionOff = "animated rotateIn";
    var h3BounceOff = "animated bounceOut";
    var pFlipOff = "animated flipOutX";


    jQuery(".procaption").on("mouseenter", function () {

        jQuery(this).find("img").addClass(imgRotacion).one(animationend, function () {
            jQuery(this).hide();
            jQuery(this).parent().find("h3").removeClass("hidden").addClass(h3Bounce).one(animationend, function () {
                jQuery(this).parent().find("p").removeClass("hidden").addClass(pFlip);
            });
        });
    });


    jQuery(".procaption").on("mouseleave", function () {
        jQuery(this).find("p").removeClass().addClass(pFlipOff).one(animationend, function () {
            jQuery(this).removeClass().addClass("hidden");
            jQuery(this).parent().find("h3").removeClass().addClass(h3BounceOff).one(animationend, function () {
                jQuery(this).removeClass().addClass("hidden");
                jQuery(this).parent().find("img").removeClass(imgRotacion).show().addClass(imgRotacionOff);
            });
        });
    });


});

The HTML structure is fairly simple:

<div class="procaption wow fadeInLeft well text-center">
      <img src="holder.js/150x150" alt="150x150" class="img-responsive img-circle center-block">

      <h3 class="hidden">This is a title</h3>

      <p class="hidden">But this is a description!</p>
</div>

The desired behavior: My goal is to sequence all the animations so they appear and disappear in a specific order upon mouseenter and mouseleave events.

Currently, it seems to be "working", but only when the mouseleave event is triggered after the last animation of the mouseenter event has completed.

When I attempt to quickly do a mouseenter followed by a mouseleave, the

<p>But this is a description!</p>
line appears simultaneously with the <img>... This should not occur!

Here's the link to the jsFiddle.

I believe there must be a simpler solution, but as I'm still learning and practicing, any guidance or suggestions would be greatly appreciated!

Just to mention, I attempted changing the .procaption class to .procaptioning during the animation until the final callback completes, but it didn't work :( I also tried using

$(".procaptioning").on("mouseenter mouseleave", function() { return false; })
... without success.

Answer №1

Your usage of .removeClass() is causing issues as it is not targeting specific elements. This can lead to unexpected results when quickly hovering on and off, as overlapping functions may interfere without clear instructions on which classes to remove at each step. I have simplified the code by minimizing nested this references and ensuring consistent selectors are used. You can view a working example in this FIDDLE.

function onHoverIn(e) {
    var $caption = jQuery(this),
        $image = $caption.find('img'),
        $h3 = $caption.find('h3'),
        $desc = $caption.find('p');

    $image.addClass(imgRotacion).one(animationend, function () {
        $image.addClass('hidden');
        $h3.removeClass('hidden').addClass(h3Bounce).one(animationend, function () {
            $desc.removeClass(pFlipOff + ' hidden').addClass(pFlip);
        });
    });
}

function onHoverOut(e) {
    var $caption = jQuery(this),
        $image = $caption.find('img'),
        $h3 = $caption.find('h3'),
        $desc = $caption.find('p');

    $desc.removeClass(pFlip).addClass(pFlipOff).one(animationend, function () {
        $desc.removeClass(pFlipOff).addClass('hidden');
        $h3.removeClass(h3Bounce).addClass(h3BounceOff).one(animationend, function () {
            $h3.removeClass(h3BounceOff).addClass('hidden');
            $image.removeClass(imgRotacion).removeClass('hidden').addClass(imgRotacionOff);
        });
    });
}

jQuery(".procaption").hover(onHoverIn, onHoverOut);

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

Is it possible to dynamically incorporate directives within an AngularJS application?

I'm attempting to utilize several custom directives within the Ionic framework. The dynamic structure is like <mydir-{{type}}, where {{type}} will be determined by services and scope variables, with possible values such as radio, checkbox, select, ...

Exploring the use of global variables in React

Welcome to my React learning journey! I've encountered an issue while trying to access a global variable exposed by a browser extension that I'm using. Initially, I attempted to check for the availability of the variable in the componentDidMount ...

Concurrent HTTP Requests - AngularJS

My directive, known as machineForm, includes a dataService: dataService.getMachineTaxesById($scope.machineId).then(function (response) { $scope.machine.machineTaxes = response.data; }); I am using this directive twice simultaneously. <div class= ...

Prevent the parent from adjusting to fit the child's content

Recently, I've been working on creating a horizontal menu bar and I have condensed the CSS as much as possible. However, I am facing an issue where I do not want the ul li element to adjust its size based on the content of the ul ul. Any suggestions o ...

What is the best way to end a table row after every group of four items?

I am working with a Handlebars template to display an array of movies in a table with four columns. Currently, I have set up a HBS helper in my code: app.engine('handlebars',exphbs({ defaultLayout: 'main', helpers: { n ...

What is the best way to include multiple entries in a select2 form using ajaxform?

select2/3.5.2/ I had to repost this because my initial post was not formatting correctly. The tools in use are: A select2 form field that allows searching through multiple records A bootstrap popup modal containing a form for entering a new record if i ...

Design a dynamic table using JavaScript

After spending hours working on my first JavaScript code, following the instructions in my textbook, I still can't get the table to display on my webpage. The id="eventList" is already included in my HTML and I've shortened the arrays. Here' ...

Adjusting the image height to match the container height while preserving its original aspect ratio

Is there a method, using CSS alone, to adjust an image's height to fit its container while preserving aspect ratio and allowing the overflow of width to be concealed? It may seem like a complex set of requirements, but is it achievable? Essentially, I ...

Bootstrap Modal Fails to Display Image Within Its Container

I'm currently working on my e-commerce website, where I'm attempting to implement a feature that allows users to view product images in a modal for a closer look. The product page contains a list of images, and when a user clicks on one, it shoul ...

Is it possible to display an element within a designated div using jQuery?

I am working with an element that I want to display in the middle of the page using a for cycle so it can be populated with the correct information. This particular element is hidden but should appear on hover. However, it doesn't look very aesthetica ...

Troubles arise when compiling TypeScript to JavaScript

I have been experimenting with TypeScript, specifically for working with classes. However, I am facing an issue after compiling my TS file into JS. Below is the TypeScript code for my class (PartenaireTSModel.ts): export namespace Partenaires { export ...

transferring iterative information via ajax data flow

My form includes hidden input fields that are manually declared in the AJAX data without a loop. How can I efficiently loop through them in the AJAX data? Below is my form script: <form method="POST" name="myform"> <?php for($i=1;$i<=5;$i+ ...

Utilizing CSS percentage height when the parent element is constrained by a defined minimum and

It is a common rule that when applying a percentage height to an element, the percentage is calculated based on its parent's height. Consider a scenario where you want a child element to be 40% of its parent's height. The parent element has both ...

Where is the best place for the heavy lifting in Redux - reducer, action, container, or presentation component?

I've been exploring the concept of container/presentational component separation as explained in this article. However, I find myself a bit confused about where certain parts of my code should be placed. Consider a simple list of items. When an item ...

Transform HTML into a Vue component dynamically during runtime

Currently, I am in the process of learning Vue and working on a simple wiki page project. The raw article data is stored in a JSON file written using custom markup. For example, the following markup: The ''sun'' is {r=black black} shoul ...

"Error encountered: Route class unable to reach local function in TypeScript Express application" #codingissues

Experiencing an 'undefined' error for the 'loglogMePleasePlease' function in the code snippet below. Requesting assistance to resolve this issue. TypeError: Cannot read property 'logMePleasePlease' of undefined This error ...

NextJS-PWA detected that the start_url was responsive, but it was not through a service worker

Recently, I incorporated next-pwa (npm link) into my workflow to streamline the service-worker setup process for building a PWA in NextJS. While most things have been smooth sailing, there's one persistent error (shown below) that continues to pop up ...

What is the best way to initiate WebXR from an iframe in a Next.js environment?

I am currently working on a Next.js app: https://codesandbox.io/s/next-js-forked-6fgnr7?file=/index.tsx I have implemented the functionality for it to open WebXR on Android Chrome when clicking on the AR button located at the bottom left ("in AR betracht ...

Can ngFor be utilized within select elements in Angular?

I'm facing an interesting challenge where I need to display multiple select tags with multiple options each, resulting in a data structure that consists of an array of arrays of objects. <div class="form-group row" *ngIf="myData"> <selec ...

Malfunctioning string error in Django view caused by boolean inconsistencies

Looking to extract variables from a post request made by Javascript. Upon inspecting the received variables in my view, I found the following: >>> print request.body {"p":"testprd","cash":false,"cheque":true,"debit":false,"credit":true} The valu ...