Simulate height: auto when using animate ()

    The task of using various animated objects on the site, such as a menu or photo gallery, has long been a rarity. And here the wonderful jquery method animate () comes to the aid of developers. This method allows you to animate various css properties, but it has one rather significant drawback - only a number or the values ​​of hide, show, and toggle can be used as the property value. For example, height: 20 is true, but height: auto will not always work and not everywhere.

    Let's try to solve this problem using a specific example.

    Let's say you need to develop a vertical two-level menu. By default, only the first level items are open, and when you click on the corresponding link, the open sublevel is hidden first, and then the desired hidden one is opened. But they do not just open, but are animated with increasing height and transparency of the container.

    That is, in the end you need to get this menu: Write the HTML code for our future menu:

    image



    Меню 1

    Меню 2

    Меню 1

    Меню 2
    Меню 2
    Меню 2

    Меню 1

    Меню 2



    Css:
    div.magic{
    filter:alpha(opacity=0);
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;
    overflow:hidden;
    padding-left:10px;
    }


    And javascript:

    $(document).ready(function(){
      $("a.menu").click(
        function(){          
          $("div.magic").animate({
          opacity: 0,
          height: "10px"
          }, 500);
              
          $("div#magic"+ this.id).animate({
          opacity: 1,
          height: "auto"
          }, 500);    
        }
      );
    })


    When you click on a menu item, we hide all the blocks of the "magic" class, and open the one that contains the items we need.

    It would seem that everything should work, but it is not so at all. Instead of the value of the “auto” height property, Firefox, Google Chrome, and Opera set the container height to 10px, which we registered in css, and IE7 generates an error: an invalid argument.

    How to deal with this?

    Method 1.

    The idea is to first write down the heights of all the necessary containers to the array before working with the menu, and then substitute the value of the element of this array instead of “auto”. That is, the new javascript code will look like this.

    $(document).ready(function(){
      var height_element= new Array();
      var array_length=$("div.magic").length;
        
      for(i=1;i<=array_length;i++)
      {
        height_element[i]=$("div#magic"+i).height();
      }
        
      $("a.menu").click(
        function(){          
          $("div.magic").animate({
          opacity: 0,
          height: "10px"
          }, 500);
            
          $("div#magic"+ this.id).animate({
          opacity: 1,
          height: height_element[this.id]+'px'
          }, 500);    
        }
      );
    })


    Thus, we will get rid of the use of the set height value equal to “auto” and replace it with a specific numerical value. This will help us get rid of the error in IE, but as it turned out, it will not solve the problem with the true value of the height of the container, because all browsers will continue to set 10px as the new value. That is, on the screen we will see this:

    image

    In order to cope with this problem, we will remove the height value from the properties of the magic class, and we will set it dynamically after writing the true height value to the array.

    The new css file will look like this:

    div.magic{
    filter:alpha(opacity=0);
    -moz-opacity: 0;
    -khtml-opacity: 0;
    opacity: 0;
    padding-left:10px;
    overflow:hidden;
    }


    And javascript like this:

    $(document).ready(function(){
      var height_element= new Array();
      var array_length=$("div.magic").length;
        
      for(i=1;i<=array_length;i++)
      {
        height_element[i]=$("div#magic"+i).height();        
      }

        $("div.magic").css("height","10px");
        
        $("a.menu").click(
        function(){          
          $("div.magic").animate({
          opacity: 0,
          height: "10px"
          }, 500);
            
          $("div#magic"+ this.id).animate({
          opacity: 1,
          height: height_element[this.id]+”px”
          }, 500);    
        }
      );
    })


    Well, for complete happiness, you can add a certain variable “first”, which will be equal to 0 after loading the page, and will take the value 1 after the first click on the menu item. It is needed in order to get rid of a delay of 500 milliseconds for hiding the open menu sublevel when all sublevels are hidden.

    You can see a working example here

    Method 2.

    Instead of the animate () method, use the hide () and show () methods with the duration of the same 500 milliseconds.

    However, when using the hide () and show () methods, all object styles smoothly change, that is, the padding we need will also change from 0 to 10 and vice versa. The effect, of course, is beautiful, but in this case it is not necessary. Therefore, padding will need to be taken out in a separate container.

    HTML for this case:

    Меню 1

    Меню 2

    Меню 1

    Меню 2
    Меню 2
    Меню 2

    Меню 1

    Меню 2


    CSS:
    div.magic{
    overflow:hidden;
    display:none;
    }

    a.menu{
    cursor:pointer;
    color:#0033CC;
    text-decoration:underline;
    margin-bottom:10px;
    }

    div.inner{
    padding-left:10px;
    }



    And javascript:

    $(document).ready(function(){
        var first=0;
        var last_id=0;
        var id_now=0;
        
        $("a.menu").click(
          function(){
            id_now=this.id;
            
            if(first!=0)
            {
              $("div#magic"+ last_id).hide(500,function(){
                $("div#magic"+ id_now).show(500);
                });
            }
            else
            {
              first=1;
              $("div#magic"+ this.id).show(500);
            }
            
            last_id=id_now;
          }
        );
      })

    * This source code was highlighted with Source Code Highlighter.

    Thanks to Voenniy for updating the second method.

    A working example can be found here.

    And as a final word . This post was not written in order to create a menu on jQuery, because there are a lot of such menus. The main goal here is to show how in two ways you can simulate the value of the height: auto property when using the animate () method. But such a task can occur not only when creating a menu.

    Also popular now: