How to put transition in a dropdown of a menu?

Asked

Viewed 2,101 times

5

I currently use the following code:

$("#menu").find('li').hover(function () {
    $(this).children('ul').clearQueue().slideDown(600);
    $(this).children('a').children('ul').clearQueue().show(0);
}, function () {
    $(this).children('ul').slideUp(300);
    $(this).children('a').children('ul').hide(0);
});

$("#menu").find('a').has( "ul" ).each(function() {
    $(this).addClass("menu-arrow");
});

He uses the .slideDown and the .slideUp. How could I leave you like the of this website?

exemplo animado do menu

When you mouse through the menu, you lower the dropdowns.

What is the name of this function? I could replace it with .slide...

HTML code in Pastebin.

  • 1

    Pure CSS already solves, take a look: http://line25.com/tutorials/how-to-create-pura-dropdown-menu

  • I prefer with jQuery. Because it’s not all browsers that work only with CSS.

  • 1

    What exactly is different between what you’re doing and what do you want to do? Is there a demo that we can look at? (e.g., jsFiddle) I saw on the site indicated that they do not use jQuery (the answer from bupereira shows what is the library and the function they use). And from what little I read of his code, it seems to me he’s doing more or less the same thing, doesn’t it? If there’s a difference, I didn’t notice...

  • They do use jQuery. Open the site with Google Chrome, put inspect element, and you will see that the menu will keep changing the value of top: causing him to rise and fall.

  • 1

    Yes @mgibsonbr using the .slide it only changes the height, already on the site I gave example, it changes the position top: that is much prettier.

  • @Alexandrelopes Now I have no time to guide you better, later I come back here. Meanwhile, I suggest looking for the demos in jQuery regarding "Effects" and "Easing". With them, should be able to customize the slide for submenus to appear and disappear as you wish (passing additional parameters to slide beyond the duration).

  • I don’t know. I’m not very good with jQuery. You could give a strength... Rsrs

  • Do you have an example of HTML for me to test? I found it difficult to understand what you want (the animation is fast, so I didn’t see the difference at first), maybe it would be good to edit the question clarifying this (I speak about the question of height and of top). jsFiddle is offline for me (and apparently, just for me...), but then I try to put together an example. Forget what I said about "Effects" and "Easing", what you want will probably involve the animate.

  • has how to post css too? da to make it easy with jQuery this

  • @Rodrigoborth is complicated to post CSS. There would be no way to only adapt by jQuery that I put in question?

  • @Alexandrelopes to no time to be able to make a functional example, but what you need to do is just give a slideDown on the mouse over and slideup on the mouse out, if you use the jQuery’s function Hover will already look like this effect, just need to adjust the speed after

  • But take a look at my jQuery. I already use the slideUp and slideDown. Only it doesn’t match the example I quoted.

Show 7 more comments

3 answers

4

I don’t know if it helps, but the JS source for showMenu function is this one:

ypSlideOutMenu.showMenu = function(id)
{
var reg = ypSlideOutMenu.Registry
var obj = ypSlideOutMenu.Registry[id]
if (obj.container) {
obj.over = true
for (menu in reg) if (id != menu) ypSlideOutMenu.hide(menu)
if (obj.hideTimer) { reg[id].hideTimer = window.clearTimeout(reg[id].hideTimer) }
if (!obj.open && !obj.aniTimer) reg[id].startSlide(true)
}

I got it from the website itself, at http://www.megahost.com.br/paginas/js/ypSlideOutMenusC.js

I hope it helps. Muril

4

The code below is a simple sample of what you might want to do. However, it is worth noting that it only transitions into two-level menus and this is not the ideal solution for smartphones. To achieve as many devices as possible within W3C standards, I recommend improving HTML, CSS and Javascript. Since I don’t have much time, I developed a very simple solution.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title>Meu menu</title>
        <style type="text/css"><!--
            .menucontainer {
                background: #eee
            }
            ul.menu, ul {
                list-style: none;
                margin: 0;
                padding: 0;
                display: block
            }
            ul.menu a {
                text-decoration: none;
                color: inherit
            }
            ul.menu li {
                display: block;
                float: left;
                position: relative;
                padding: 10px
            }
            ul.menu li:hover {
                background: #ddd
            }
            ul.menu li li {
                float: none;
                padding: 0
            }
            ul.menu li li a {
                padding: 10px;
                display: block
            }
            ul.menu li .verticalhider {
                position: absolute;
                top: 90%;
                left: 0;
                overflow: hidden
            }
            ul.menu li ul {
                display: none;
                background: #f3f3f3;
                width: 200px;
                padding: 5px;
                border: 1px dotted #555;
                position: relative
            }
            ul.menu li:hover ul {
                display: block
            }
            .clearfix {
                clear: both
            }
        //--></style>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script type="text/javascript"><!--
            (function($){
                $(function(){
                    $('.menu li > .verticalhider > ul').each(function(){
                        var u = $(this);
                        function getHeight(){
                            return u.height() + parseInt(u.css('paddingTop')) + parseInt(u.css('paddingBottom')) + parseInt(u.css('borderTopWidth')) + parseInt(u.css('borderBottomWidth'))
                        }
                        u.css({display: 'block', marginTop: -getHeight()}).parent().parent().mouseenter(function(){
                            u.stop().animate({marginTop: 0}, 200)
                        }).mouseleave(function(){
                            u.stop().animate({marginTop: -getHeight()}, 200)
                        })
                    })
                })
            })(jQuery);
        //--></script>
    </head>
    <body>
        <div class="menucontainer">
            <ul class="menu">
                <li>
                    <span>Menu 1</span>
                    <div class="verticalhider">
                        <ul>
                            <li>
                                <a href="#">Menu 1</a>
                            </li>
                            <li>
                                <a href="#">Menu 2</a>
                            </li>
                            <li>
                                <a href="#">Menu 3</a>
                            </li>
                            <li>
                                <a href="#">Menu 4</a>
                            </li>
                            <li>
                                <a href="#">Menu 5</a>
                            </li>
                        </ul>
                    </div>
                </li>
                <li>
                    <span>Menu 2</span>
                    <div class="verticalhider">
                        <ul>
                            <li>
                                <a href="#">Menu 1</a>
                            </li>
                            <li>
                                <a href="#">Menu 2</a>
                            </li>
                            <li>
                                <a href="#">Menu 3</a>
                            </li>
                        </ul>
                    </div>
                </li>
            </ul>
            <div class="clearfix"></div>
        </div>
    </body>
</html>

See you around

  • It’s only for computers anyway, for smartphones I’m using jQuery Slicknav plugin.

  • 1

    @Alexandrelopes By the way, the example of this answer seems to do exactly what you want (demo). Have you had any trouble adapting it to your particular case? Or maybe you missed something?

  • I think it would be right to edit the answer, rather than quote an example, to take the code I mentioned in the question and adapt it. I’m not good with jQuery, then I do not know how to adapt it. In the question has the jQuery and the HTML, I wanted you to adapt it to my code.

  • 2

    @Alexandrelopes Well, in my conception the idea of the OS is to answer questions, the adaptation to your particular case is still your responsibility (however, you are free not to accept an answer that does not satisfy you). For my part, I just don’t give the reward for that answer because it just plays the code and doesn’t explain, otherwise I’d accept it right away. I see that this technique works, but I don’t quite understand why. It has many CSS rules, and most of them just seem to me to support the layout, not being central to the solution of the problem. This makes it a little difficult to adapt it.

  • :( ||||||||||||

1

First, consider the possibility of a solution via pure CSS, such as pointed by dxhj in the comments. Just assign a negative margin to the submenu, and assign it to zero when the menu item is under the mouse (hovered). You can add transition effects using the property transition, when supported (most browses support it, except for IE9 or lower).

nav ul ul {
    margin-top: -120%;
    z-index: -1;
    -webkit-transition: margin 1s ease-in;
    -moz-transition: margin 1s ease-in;
    -o-transition: margin 1s ease-in;
    -ms-transition: margin 1s ease-in;
    transition: margin 1s ease-in;
}
nav ul li:hover > ul {
    margin-top: 0;
}

Example in jsFiddle. Reference 1, reference 2. Note: I’m terrible with CSS, so the example was not as good as it could be (the submenu reaches over the menu), but should serve as a basis for something more elaborate. Also, I tried using your HTML, but it contains a lot of bugs, so I adapted as I could...

P.S. The answer from Recovieira Coimbra Vieira seems to solve this problem of overflow using an extra element .verticalhider. I tried to reproduce in my example, but as the answer does not explain the reasoning behind the technique, I could not quite understand how it works. Anyway, here it is a functional example using the code of that answer.

If you really need to use jQuery (even if it’s for browsers that don’t support jQuery transition), the code of the slideDown - which second that answer in Soen is made through a call from animate - so as not to vary the height, but rather the margin-top:

$("nav > ul > li").hover(function () {
    $(this).children('ul').clearQueue().animate({
        //"height": "show",
        "marginTop": 0, //"show",
        "marginBottom": "show",
        "paddingTop": "show",
        "paddingBottom": "show"
    }, 1000);
    $(this).children('a').children('ul').clearQueue().show(0);
}, function () {
    $(this).children('ul').animate({
        //"height": "hide",
        "marginTop": "-120%", //"hide",
        "marginBottom": "hide",
        "paddingTop": "hide",
        "paddingBottom": "hide"
    }, 1000);
    $(this).children('a').children('ul').hide(0);
});

Example in jsFiddle.

  • Thank you! I will perform some tests.

  • I put yours here .animate And he got all flustered. He’s not at all like the example I gave. When you take the mouse off it only goes up to half, then it disappears from the "nothing".

  • Since CSS is not my strong suit, I’ll let someone better in this area answer then. As for disappearing from nowhere, I think if you cheer up the height as to the top help - it will only get 2x faster (you can adjust the delay in agreement). Now, as for going up to half, you can’t guess without seeing your Markup... If you prefer not to show, it is your right, but in this case you are on your own.

  • I’ll show you. I’ll show you.

  • http://pastebin.com/sxBpK6cY

  • 1

    @Alexandrelopes I couldn’t, I really suck with CSS, and I couldn’t find anything in jQuery that would help... But I’m also interested in an answer, so I’m putting a reward on that question.

  • \o/ Legal!.....

  • 1

    mano has how to post the code of your CSS?

  • @Alexandrelopes Well, it’s only a few hours before the reward ends, and no one has spoken... I edited my answer with all the information I could gather, including an example with your code (adapted; there are many HTML errors in it, so I could not use it as it is).

  • :Thank you for everything @mgibsonbr you are 10!

  • 1

    @mgibsonbr I have restructured your CSS, see if you can take advantage of something: http://jsfiddle.net/ahobngoe/3 . In short, I used an overflow:Hidden on Nav to eliminate the top of the menu, and rethought the whole structure a bit. I took a little bit of the extra detail (gradients, etc.) to focus more on the essential CSS, and re-ordered by "depth" for easy maintenance. I just need to see how to do the Gambi 180% get more predictable. (then I delete this comment here)

  • A px version instead of %: http://fiddle.jshell.net/ahobngoe/6/

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.