Question

I'm currently making a little navigation menu. In one of those dropdown menus, I need one category to expand. It works. But, when category retracts with the help of jQuery .hide('slow'), the menu I want to hide blinks once at the end of the hide animation, and then is properly hidden.

Here's some code below to illustrate my problem :

$(document).ready(function(){

    var verif = false;

        $("a").hover(function() {

        var texte = $(this).text();
        var tab = new Array;
        tab = texte.split("      ");
            if (tab[0] === "+ Deroule" && verif === false) {
                    $("#submenu").show("slow");
                    verif = true;
            }
            else if (tab[0] === "+ Deroule" && verif === true) {
                        $("#submenu").hide(8000);

 //There, I can clearly see, at the end of the hide animation, the previously opened content blinking once before it hides completely.

                                                     verif = false;
                }                                               
        }); 
});
Was it helpful?

Solution

Without seeing your HTML/CSS it's hard to actually pin the problem down - hint hint create a fiddle hint hint :) - but the first thing that I would do, if I were you, is change the .hover() method to .mouseenter() and .mouseleave() (NOT .mousein() and .mouseout() - that's another conversation about IE support - you can/should look that up on jQuery's site, if you're not familiar).

Why do this? The .hover() method is actually just shorthand for .mouseenter()/.mouseleave() but, for various reasons (including the fact that it is not as widely supported as the two full methods), it occasionally fails to work properly. I cannot guarantee that this is the problem in this situation, but, especially since this appears to be a browser issue, it is always best to go back to basics and start with as much support as possible.

EDIT:

After seeing your simplified fiddle, I think I have a better understanding of what your issue is and what you're trying to do. I have had the same issue before and, from my experience, I can tell you that it is actually a difficult issue to account for.

Elements jump when they are shown/hidden using the .show(), .hide(), slide, and fade methods because as soon as the animation completes they are removed from the flow (in most browsers - not chrome - the show/hide methods do not cause the element to shrink all the way to nothing, so there is still choppiness). Here are two of my most recent solutions to this issue:

In one situation, I was tasked with creating view-more and view-less buttons inside a menu, which would make elements appear/disappear SMOOTHLY one at a time. If you simply try to call a show/hide, slide, or fade method on the collection to be shown, they will all animate at the same time, and the same thing happens when trying to make them run on callback. Additionally, sliding methods wouldn't work because this animation was going to be called on multiple items at a time, thus causing a lot of overhead and making the effect choppy in slower browsers (and even a bit in FF). The show/hide methods worked in some browsers, as they actually do reduce the size of the element, but they are choppy in others so they were out (effectively, their animations don't "complete" in all browsers - see above). Thus, I was left with three options: use fade, animate, or a combination of both.

Solution 1: The original plan, as it was (with the given specs) the best solution at the time, was to use the animate method to simply slide a wrapper div (with overflow set to hidden up or down, based on the offset of a target element in the list). This worked great, but I was then given the requirement of having each element disappear in succession, via a fade effect. If you do choose this method, then I suggest that you instead use slide methods - as you are not attempting to show view more/less links, this shouldn't be a problem (yes, I know that this probably doesn't sound like it would be an issue for view more/less links, but the way I had to implement it, slides actually did cause an issue).

Solution 2: Using fade on its own was an issue because everything was still going to fade at the same time and, even if they didn't, the animation would still jump once the fade finished. Thus, the first issue I needed to solve was the animations running at the same time. Using a timer was out of the question because of the overhead, so I wrote a function that recursively called the fade on each element in the collection after calculating the necessary delay between calls (based on a supplied speed argument, and the number of elements to be faded). Next, I still had to solve the jumping issue once the animations were complete. To fix this, I implemented the .fadeTo() method, thus keeping the elements in the flow of the document after their animations. This did, however, cause two more issues:

  1. The .fadeTo() method is not supported in IE (it may be in 9 and 10 - I can't remember)
  2. After the animation, there was a lot of empty space due to the elements not being removed from the flow

To remedy the first issue, I added a browser-specific method for IE, which set the display property of each element to block and their visibility to hidden once their fade-outs were completed - it also did the reverse just before their fade-ins were started.

I solved the second issue by using the animation method that I described previously. To make this work, I had to write another auxiliary method that calculated the speed at which the container needed to slide, based on a given speed of the animation and the number of elements being shown/hidden.


I know that this was a lot of detail, but I hope it helps you determine how best to go about this.

Let me know if you have any questions or need any clarification when you move forward with your implementation. Good luck! :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top