jQuery 关于点击菜单项,使子条目"向上"展开效果的实现

为何作了这样一个的功能呢?缘由是前一段时间jQuery群里有个朋友想实现这样一个东东,你们都知道jQuery中有现成的slideDown和slideUp方法,但那是向下展开,而这个是一个彻底相反的效果。css

功能展现连接 http://runjs.cn/detail/v6i9g6g0html

其实这样一个功能也蛮奇怪的,感受不是很实用,可是当时也没有一会儿作出来,试着写了一下子以为不能立刻写完就say sorry了。ide

最近呢又开始接着继续学习jQuery的东西,学到animate动画的时候,本身就在想,是否是能够用来实现一下这个功能呢(这个真是个心结啊~~)?而后就试着写了一下,通过一番波折,不只让我对animate的使用更加了解以外,也让我了解了一个用jQuery的小技巧,更重要的是,实现这个功能。学习

下面上代码并作出解析:动画

Html部分:this

    <div>
        <span>Item1.1</span>
        <span>Item1.2</span>
        <span>Item1.3</span>
        <span>Item1.4</span>
    </div>
    <div>
        <span>Item2.1</span>
        <span>Item2.2</span>
        <span>Item2.3</span>
        <span>Item2.4</span>
    </div>
    <div>
        <span>Item3.1</span>
        <span>Item3.2</span>
    </div>
    <div>
        <span>Item4.1</span>
        <span>Item4.2</span>
    </div>
    <div class="menu">
        <span>Item1</span>
        <span>Item2</span>
        <span>Item3</span>
        <span>Item4</span>
    </div>

文档结构是这样子的,你们能够看到menu这个主菜单的菜单项的顺序与子菜单的实际顺序是一致的。这个是为点击菜单项上的条目经过位置查找对应子项作的一个设计。spa

jQuery部分:设计

        $(function () {
            $("div").each(function () {//遍历全部div元素
                if ($(this).is("[class='menu']")) {//若是是菜单所在的div
                    $(this).css({ "top": $(this).height() + $(this).position().top,
                        "position": "absolute",
                        "color": "white",
                        "background-color": "white",
                        "width": "500px",
                        "left": "200px"
                    })//为菜单添加样式
                    .children("span").css({ "background-color": "DimGrey",
                        "border": "black solid thin"
                    })//为菜单项添加样式
                    .each(function () {//对每一个菜单项进行遍历
                        $(this).click(function () {//添加click事件
                            var Ind = $("div.menu").children().index(this);//找出当前点击的菜单项是菜单div中的第几个span
                            var FocusEle = $("div:eq(" + Ind + ")");//将选中菜单项的子项设成一个变量
                            if ($("div[class*='up']").size() == 0) {//说明是第一次加载,初次的时候为没选中任何菜单项的状态,因此up的个数为0
                                FocusEle.animate(
                                {
                                    top: $(this).height() - 10//使对应的子项向上移动
                                },
                                'normal',//中速移动
                                function () {
                                    $(this).addClass("up");//移动完以后为这个子项加上up的样式
                                });
                            } else {//若是不是初次加载
                                $("div[class*='up']").animate(//找到正在显示的菜单子项
                                {
                                    top: $(this).height() + 10//使对应子项向下移动
                                },
                                'normal',
                                function () {
                                    $(this).removeClass("up");//移除这个子项的up样式
                                    FocusEle.animate(//一
                                    {
                                        top: $(this).height() - 10//将从新选中的菜单子项向上移动
                                    },
                                    'normal',
                                    function () {
                                        $(this).addClass("up");//添加up样式
                                    });
                                })
                                //***************************特别说明**********************
//                                .queue(function () {二
//                                    FocusEle.animate(
//                                    {
//                                        top: $(this).height() - 10
//                                    },
//                                    'slow',
//                                    function () {
//                                        $(this).addClass("up");
//                                    });
//                                });
                            }

                        }).css("cursor", "pointer").hover(function () {
                            $(this).css("color", "red");
                        }, function () {
                            $(this).css("color", "white");
                        })
                    });
                }
                else {//若是不是菜单所在的div,即菜单子项
                    var Index = $("div").index(this);
                    var Left = $("div.menu span:eq(" + Index + ")").position().left + 200;//修改不一样子项的横坐标,使其与菜单项的条目一致
                    $(this).css({ "top": $(this).height() + $(this).position().top,
                        "left": Left,
                        "color": "white",
                        "position": "absolute"
                    })//为菜单子项添加样式
                    .children().css({
                        "background-color": "SlateGrey",
                        "border": "black solid thin",
                        "cursor": "pointer"
                    }).hover(function () {
                        $(this).css("color", "red");
                    }, function () {
                        $(this).css("color", "white");
                    });
                }
            })
        });

上面的代码几乎是逐条注释的,你们应该都能看懂,主要的实现思想我仍是说一下,你们再结合着注释看就OK了,你们会发现实现这个功能的时候彻底没有显示(show()),隐藏(hide())的操做,最开始我也是一个思惟误区,觉得必需要用显示,隐藏去实现,但作着作着发现了一个很是傻的问题,展开的效果实现上是经过移动隐藏和显示来实现的。怎么说呢,你们想一想看完电影以后演员名单那部分的东西就能有个概念了。orm

这里有两点很重要:htm

一、这5个div所有为absolute形式的,由于只有这样才能进行相对移动

二、所谓的消失,其实是4个子项的div被menu div也遮挡住了,因此这里要知道,我给menu div加了背景色,即白色。

说到这你们应该就知道是如何实现的了吧?

另外在说一 下 注释中”特别说明”的那部分,其实这部分代码与它上面不远处的【一】的代码是同样的,只是前面加了.queue这么东西,这是作什么的呢?就是将多个动画放到一个队列里,而后依据队列的次序,一个一个的展示出来。个人初衷就是,若是当前有子项是展开状态的,那么就“先”把其关闭,“后”把新点击的子项展开。

不过不知道为何,若是是二次进行了点击的子项,就不会再通过queue 中animate结束时那个function了。这个有明白为何的朋友能够帮忙解答一下。然而像我【一】中这个实现,也是合乎规则的。

其实这个小功能还有点弊端,就是若是点击过快,你们会发现同时展开多项子菜单,缘由是动画的过程是须要时间的,而在这段时间里我没有禁止click事件。应该是用指派命名空间的方法就能够搞定。你们能够研究研究而后告诉我。

最后总结了一下,写这个小功能有点惭愧的说写了挺长时间,中间换了好多方法为解决一些问题,如今看来,这么简单的东西为何会写这么久,仍是由于最开始的时候没有想好,边写边想花费了许多时间。之后要改进这种作事方法。


新浪微博:http://weibo.com/zhouhongyu1989 欢迎围观~!

相关文章
相关标签/搜索