When using jQuery, adding a class does not always trigger CSS animation

Currently facing a peculiar issue. I am utilizing jQuery to load articles from JSON and would like to dynamically add a class of 'animate' to each loaded element.

$.each(jsonArticles, function (i, article) {

    var $articleHTML = $(
    '<article class="article">' +
        '<a href="' + jsonObject.filmLink + article.reviewLink + '"><img src="' + jsonObject.imagePath + article.reviewImage + '" alt=""></a>' +
        '<h1><a href="' + jsonObject.filmLink + article.reviewLink + '">' + article.reviewTitle + '</a></h1>' +
        '<p><a href="' + jsonObject.filmLink + article.reviewLink + '">' + article.reviewSummary + '</a></p>' +
    '</article>');

    $articles
        .append($articleHTML)
            .find("article")
                .addClass("animate");

});

The addition of the class works well as verified in Firebug where it shows up for each article tag.

However, when attempting to apply a CSS transition to animate the class added to the article, there is no animation and it instantly switches to the final style (opacity: 1).

.article { 

opacity: 0;

    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;

}

.article.animate { 

    opacity: 1;

}

The expected animation does not occur despite the class being added and successfully setting the article to opacity: 1. It appears abruptly.

If the .animate class is modified to include a :hover, then the articles will only appear on hovering with the animation working as intended. This inconsistency between immediate addition and hover effects is puzzling.

.article.animate:hover { 

    opacity: 1;

}

Your insights on this matter are highly appreciated.

Thank you, Mikey.


Live Demo: http://jsfiddle.net/Pz5CD/ Observe how the articles abruptly display at full opacity without any animation.

Answer №1

Important Update:

Upon further examination, it has been discovered that the original poster (OP) actually desires a sequential fading effect for each element, which goes beyond the initial query. Nevertheless, I will retain my response to address the initial question.

Challenge with CSS Animations not Triggering on addClass in jQuery

The root cause of the issue lies in the fact that the new HTML content is inserted into the page and the `animate` class is added before the corresponding CSS styles are fully applied. To optimize performance, browsers tend to skip ahead in such scenarios. For instance, if you were to repeatedly add and remove a class multiple times consecutively, there would be no visible change as the browser would simply jump to the final outcome. Therefore, to ensure proper execution, you need to force a redraw on the element so that all preceding styles can take effect before adding the class. Below is a function that addresses this issue and should work reliably across various browsers, although the behavior of a reDraw cannot be guaranteed. Nevertheless, it typically functions as intended and offers a useful solution!

Check out the live demo here (click). You can observe the impact of the reDraw by commenting it out and solely leaving the `addClass()` function.

$('body').append($articleHTML);
$a = $('body').find("article");
reDraw($a).then(function() {
  $a.addClass("animate");
});

function reDraw($element) {
  var deferred = new $.Deferred();
  setTimeout(function() {
    var h = $element[0].offsetHeight;
    var s = $element[0].getComputedStyle;
    deferred.resolve();
  }, 0);
  return deferred.promise();
}

The most effective method to trigger a redraw is by accessing either the `offsetHeight` or `getComputedStyle` of an element. However, in some instances, these methods may fail to induce a redraw on specific mobile devices. To reinforce the redraw process, I have included a `setTimeout` as well. Even a minimal timeout value of 0 will suffice, but to maintain the call stack order, I utilize a promise to ensure that the subsequent operation (adding your class) occurs post-redraw. This necessitates using the syntax exemplified above to incorporate the class - `redraw($element).then(function() { //your code`.

As a fun exercise, I created a demonstration showcasing class transitions with and without reDraw for comparison. Experience it here: http://jsbin.com/EjArIrik/1/edit

Answer №2

In order to apply the class to the element once it has been displayed on the screen, consider using a setTimeout function

setTimeout(function(){
    $articleHTML.addClass("animate");
}, index * 500 );

http://jsfiddle.net/Pz5CD/1/

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

Exploring the Dynamic Duo: Laravel Echo and JQuery

After including Echo in Vue.js' resources/assets/js/bootstrap.js, one of my components is throwing an error The error message states: "Error in mounted hook: 'TypeError: $ is not a function'" When I remove the Echo import, everything run ...

Attempting to grasp the fundamentals of angular Routing, however, upon attempting to reload the page, nothing appears to be displayed

While working in the Bracket editor, I created a file structure with various files located under the 'scripts' tags within the Index.html file. The root folder is named 'projectAngular', inside which there are subfolders like 'appC ...

Are multiple instances of ajax being executed within the modal?

Currently, I am working on a feature that requires an Ajax request. To begin with, the process involves opening a modal by clicking a button with the class '.open-email-modal'. Within this modal, there are two input fields to enter registration d ...

Leverage information retrieved from API in a separate React component

Is there a way to fetch data from an API in one component and then access it in another component without having to re-fetch the data? For example, if I fetch some data and create a table in Tables.js, how can I use that same data in TableDetails.js withou ...

Error animation on client-side validation not resetting correctly

Incorporated a form validation and error display system utilizing TransitionGroup for animations. The flag issueVisible manages the visibility of the error message, while determineField() aids in identifying the field related to the error. The issue arise ...

Troubleshooting the issue of data retrieval failure in asp.net mvc controller using jquery.post()

I am currently working on an ASP.NET MVC web application that is written in VB.NET. My goal is to send data using jQuery to my controller. Below is the code for my controller: <HttpPost()> Function GetData(p As DataManager) As JsonResult ...

Angular's responsiveness is enhanced by CSS Grid technology

I am attempting to integrate a CSS grid template that should function in the following manner: Columns with equal width 1st and 3rd rows - 2 columns 2nd row - 3 columns https://i.sstatic.net/aQyNR.png Order = [{ details:[ { ke ...

Is there a simple method to automatically increase the version number of Mongoose documents with each update request?

I'm eager to utilize Mongooses document versioning feature with the "__v" key. Initially, I struggled with incrementing the version value until I learned that adding this.increment() when executing a query is necessary. Is there a method to have this ...

JSON.Parse allows for graceful degradation of data when handling JSON objects in JavaScript

What should be done if a browser does not support JSON.parse? Would it be appropriate to include json.js and use parseJSON instead? Here's an example of how the code could look: var output; if (JSON.parse) output = JSON.parse(data); else ou ...

The React Hook useEffect is missing a dependency: 'handleLogout'. Make sure to either add it to the dependency array or remove it from the useEffect hook

import { useState, useEffect } from "react"; import LoginModal from "./LoginModal"; import { NavLink, useLocation, useNavigate } from "react-router-dom"; import { useDispatch } from "react-redux"; import { userLogout ...

Ensuring that the bootstrap5 column extends all the way to the footer

Looking to display a specific email address mailbox for a project. The goal is to have the 'Mail Card List' scrollable instead of extending beyond the page. Tried using 'max-height:;' CSS, but it sets a fixed height. Seeking a variable ...

Tips on waiting for Vue component's asynchronous mount to complete before proceeding with testing

In my Vue2 component, I have an asynchronous lifecycle hook method: // create report when component is loading async mounted(): Promise<void> { await this.createReport(); } Now, I want to test my component using jest and vue/test-utils, but the te ...

When setting up Vue.js for unit testing, the default installation may show a message stating that

Recently set up a fresh Vue project on Windows 7 using the VueJS UI utility. Unit testing with Jest enabled and added babel to the mix. However, when running "npm test" in the command line, an error is returned stating 'Error: no test specified' ...

Utilizing Spring Boot to Retrieve a File in JavaScript Code Without Activating a Controller

I am working on a Spring Boot project that utilizes plain JavaScript and jQuery. I need to load a .ttf font for a JS plugin without involving a controller. The goal is for the JS code to simply read the file from the project folder. Do you think this ca ...

Utilizing nested routes in Node.js with express.js framework!

index.js const AuthRouter = require("./Routes/Auth/signup") app.use("/account", AuthRouter) signup.js router.post("/", async (req, res) => { res.send("Signup") }) It's functioning correctly... H ...

Highlight the active page or section dynamically using HTML and jQuery - How can it be achieved?

What am I trying to achieve? I am attempting to use jQuery to dynamically highlight the current page from the navigation bar. Am I new to jQuery/HTML? Yes, please excuse my lack of experience in this area. Have I exhausted all resources looking for a sol ...

Executing a callback function within two nested functions

I am having trouble with the callback function that is being called inside a function which in turn calls another function. exports.user = function(userName, pwd, callback) { db.User.findOne({'userName': userName}, function(error, obj) { ...

The resume button is failing to activate any functions

I recently encountered an issue with a JS file that is associated with a Wordpress Plugin, specifically a Quiz plugin featuring a timer. I successfully added a Pause and resume button to the quiz, which effectively pauses and resumes the timer. However, I ...

What is the best way to display items using Typeahead.js in combination with the Bloodhound engine?

I am struggling to showcase a collection of items using typeahead with a JSON file as the data source. Unfortunately, none of my information is appearing on the screen. My objective is to list the names and utilize the other attributes for different purpo ...

Displaying tooltips with ngx-charts in Angular

Currently, I am working on developing a unique legend component that features individual material progress bars for each data entry. My goal is to display the pie chart tooltip when hovering over any of the entries within this custom legend. Below is a sn ...