The art of jQuery: Effortlessly animate the deletion of a CSS property

When using jQuery, I often "collapse" certain DOM elements by decreasing their width to 0px and fading them out. Here is an example:

$(".slideoutmenu").animate({ width: 0, opacity: 0}, function() { $(this).hide(); }); 

The widths of these elements can vary, but the document layout is set up correctly through CSS without specifying a specific width.

To show these elements again, you could simply do something like this:

$(".slideoutmenu").stop().show().css({ width: '', opacity: 1 });

However, I want to animate these elements in reverse (fade in and expand).

Normally, I would use something like this:

$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });

So here's what I tried:

$(this).children(".slideoutmenu").stop().show().animate({ width: "", opacity: 1 });

Unfortunately, this approach didn't work as expected.

The issue lies in the fixed "250" value used above. Since the widths are variable, I need to find a way to combine the result of setting an empty string for the width and animating it, but I haven't been able to figure it out. I've experimented with different values like 'undefined', 'null', '-1', '' without success.

I know I could potentially manipulate measurements while keeping the element hidden from the user, but I believe this must be a common problem and there should be a standard solution available, or perhaps it's built into jQuery in some way that I'm unaware of.

Thank you for reading.

FOLLOW UP:

After receiving helpful input from Michael, I created a simple plugin to achieve this functionality dynamically. Below is the plugin code:

(function( $ ){

  $.fn.cacheCss = function( prop ) {  

    return this.each(function() {

      var $this = $(this);

         if (prop instanceof Array)
        {
            for (var pname in prop)
            {
                if ($this.data('cssCache-' + prop[pname]) != undefined)
                    continue;

                $this.data('cssCache-' + prop[pname], $this.css(prop[pname]));
            }
        }
        else
        {
            if ($this.data('cssCache-' + prop) != undefined)
                return $this;

            $this.data('cssCache-' + prop, $this.css(prop));
        }

        return $this;

    });

  };


  $.fn.revertCss = function(settings, prop, animated) {  

    if (settings == null)
        settings = {};

    return this.each(function() {

      var $this = $(this);

        if (prop instanceof Array)
        {
            for (var pname in prop)
            {
                if ($this.data('cssCache-' + prop[pname]) != undefined)
                    settings[prop[pname]] = $this.data('cssCache-' + prop[pname]).replace(/px$/, "");               
            }
        }
        else
        {
            if ($this.data('cssCache-' + prop) != undefined)
                settings[prop] = $this.data('cssCache-' + prop).replace(/px$/, "");
        }

        if (!animated)
          return $this.css(settings);

        return $this.animate(settings);

    });

  };

})( jQuery );

Here is how I implemented the plugin with my existing code:

The original line that set the css property:

$(".slideoutmenu").animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 

was replaced with:

$(".slideoutmenu").cacheCss('width').animate({ width: 0, opacity: 0}, function() { $(this).hide(); }); 

The ".cacheCss('width')" now caches the value of the css property before starting the animation.

And when I needed to revert those changes:

$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });

was replaced with:

$(this).children(".slideoutmenu").stop().show().revertCss({ opacity: 1 }, 'width', true);

Now, ".revertCss(...)" uses the cached settings to revert the width property in an animated manner.

The plugin also accepts arrays, allowing you to cache multiple properties and then revert them together:

.cacheCss(['width', 'height'])

and later:

.revertCss(null, ['width', 'height'], true)

The third parameter specifies whether the reversion should be animated or not.

If you have other properties to animate alongside (e.g., 'opacity' as shown earlier), you can pass them in just like you would for the .animate() function.

I believe this plugin has room for improvement, but thought it might still be useful to share.

Lastly, I had to remove extra "px" at the end of the css values using a basic regex – there may be a more efficient method for doing this.

Answer №1

To preserve the original width of an element before animating it, you can utilize jQuery data:

$(".slideoutmenu").each(function(){
    $(this).data('width', $(this).css('width'));
    $(this).animate({ 
        width: 0, 
        opacity: 0 
    }); 
});

$(".slideoutmenu").each(function(){
    $(this).children(".slideoutmenu").stop().animate({ 
        width: $(this).data('width'), 
        opacity: 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

Using AJAX to Post Data with Relative Path in ASP.NET MVC 5

I have been developing an MVC 5 web application that utilizes AJAX Posts to invoke Controller Actions. For example, I have a controller named "Account" with an action called "Create". In my Account/Index view, which is rendered by accessing an Account/Ind ...

Retrieving the value of a radio button using jQuery and Ajax

Looking for assistance with radio buttons... <input type="radio" id="flip" name="flip" value="Head" checked="checked" /> Head <input type="radio" id="flip" name="flip" value="Tail" /> Tail I'm attempting to process a form with ajax, try ...

Error message: "Property undefined when Angular attempts to call a function from jQuery/JavaScript."

I'm currently attempting to invoke an angular controller from my JavaScript code. This is my first encounter with Angular and I must admit, I'm feeling a bit overwhelmed! I've been following this example: Unfortunately, when testing it out ...

What is the best way to incorporate a fresh array into the existing array element stored in local storage?

I stored a group of users in the local storage: let btnSignUp = document.getElementById("btnSignUp"); btnSignUp.addEventListener('click', (e) => { let existingUsers = JSON.parse(localStorage.getItem("allUsers")); if (existingUsers == null ...

Using justify-content-between in a div container with only two items will not produce the desired effect

I'm having trouble aligning two elements on opposite ends of a div container using Bootstrap's justify-content-between class. The h4 element is not on the left and the button on the right as expected. I am using Bootstrap 5.2.3. Can anyone help m ...

Sending a request to a PHP file using Ajax in order to display information fetched from

I am attempting to display the database row that corresponds with the student's forename and surname selected from the dropdown list. I have managed to store the first name and surname in a variable called clickeditem. However, I suspect there may be ...

Node.js is struggling to parse JSON data, resulting in undefined values appearing in the console

Issue with parsing JSON data in a node.js environment resulting in 'undefined' display in console. Below is the HTML code snippet: var jsonObjects = [{id:1, name:"amit"}]; jQuery.ajax({ url: 'http://localhost:8081', type: ...

Tips for eliminating the border on a Twitter widget

Looking to integrate a Twitter widget into my website. The site is built using Smarty and I want to customize the widget. Currently, there is a scroll bar on the right section that I would like to remove by adding a style overflow:hidden to the class strea ...

Making an AJAX POST request with jQuery to a specific subdomain

I am experiencing difficulties with an Ajax Request across different SubDomains. The PHP Script responsible for handling the request can be found at account.domain.com/login Despite having multiple SubDomains, the Ajax request is accessible from all of t ...

Enhancing User Experience: Real-Time Preview in Text Area using Jquery

I have a code snippet here that allows me to insert images into a textarea and display a live preview when I click on a div. However, there is a small issue with the image not appearing instantly in the textarea; instead, I have to type a character for it ...

Looking for an Icon to accompany the navigation bar on Bootstrap

Can anyone assist me with adding an icon next to the navbar starting from the word "Dashboard" without any spacing using only Bootstrap? Please note that I have tried options like offset-5 and ms-5 but they did not achieve the desired result. <div id=& ...

Retrieve Vue.js component property within an Ajax function

When dealing with a component function that fetches data from an URL and attempts to set that data to a property, there seems to be an issue where this is not accessible from the AJAX closure scope. var MyComp = Vue.extend({ props: { html_pro ...

Adding a CSS style to specific sections of a string that is quoted in a Razor ASP.NET file

Is it possible to format a specific part of a string? I'm trying to only stylize the word within quotation marks. This is my cshtml code: { <div class="h-44 overflow-auto text-left mx-4 mb-4"> <p ...

Modification of a CSS element

The CSS I am working with looks like this: .cls .imageX { float:left; } .cls .imageY { float:right; } It is currently being used on a page in this way: <div class="cls"> <a href="" class="imageX"><img src="left.png"/></a> &l ...

What is the best way to split a Bootstrap row into five equal-sized columns?

Trying to divide a Bootstrap row into five columns can be tricky when you only have 12 units available on the device. How can this division be achieved successfully? ...

Handling mousewheel events for child elements and their parent element

I developed a custom jQuery plugin that replaces the default scrollbar with my own, managing mousewheel and bar dragging events. The issue arises when I place content containing my custom scrollbar within another content also using my scrollbar. When I sc ...

Tips for styling your Angular Material Card on mobile devices

Currently, I am very happy with my desktop layout which looks like this: https://i.stack.imgur.com/tG0pw.png However, when it comes to the mobile version of my site, here is what I have so far: https://i.stack.imgur.com/KD1hh.jpg While I do like the ho ...

Ways to ensure consistent element size on various devices

I am looking to maintain a fixed size for an element across different devices in reality, such as 6 x 3 cm. Currently, I have set it to 400 X 200 px and adjusted the layout accordingly (like single column display for smaller screens). While this setup wor ...

"Exploring the process of looping through a JSON object following an asynchronous retrieval of JSON data using

I am facing an issue while trying to iterate through a JSON object in jQuery after fetching it asynchronously. I have a function called 'listFiles' that uses async to successfully retrieve a file list from a directory (dir) by calling an API endp ...

Implementing a line break within a JavaScript function specifically designed for formatting images

As I am not a javascript developer, the code I have been given for debugging is somewhat challenging. The issue at hand involves an iOS module where a .js CSS file has been set up and images are loading improperly, resulting in the need for horizontal scro ...