zoukankan      html  css  js  c++  java
  • jQuery 关于点击菜单项,使子条目“向上”展开效果的实现

    为什么做了这样一个的功能呢?原因是前一段时间jQuery群里有个朋友想实现这样一个东东,大家都知道jQuery中有现成的slideDown和slideUp方法,但那是向下展开,而这个是一个完全相反的效果。

    功能展示链接 http://runjs.cn/detail/v6i9g6g0

    其实这样一个功能也蛮奇怪的,感觉不是很实用,但是当时也没有一下子做出来,试着写了一会儿觉得不能马上写完就say sorry了。

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

    下面上代码并做出解析:

    Html部分:

        <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这个主菜单的菜单项的顺序与子菜单的实际顺序是一致的。这个是为点击菜单项上的条目通过位置查找对应子项做的一个设计。

    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())的操作,最开始我也是一个思维误区,以为必须要用显示,隐藏去实现,但做着做着发现了一个非常傻的问题,展开的效果实现上是通过移动隐藏和显示来实现的。怎么说呢,大家想想看完电影之后演员名单那部分的东西就能有个概念了。

    这里有两点很重要:

    1、这5个div全部为absolute形式的,因为只有这样才能进行相对移动

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

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

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

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

    其实这个小功能还有点弊端,就是如果点击过快,大家会发现同时展开多项子菜单,原因是动画的过程是需要时间的,而在这段时间里我没有禁止click事件。应该是用指派命名空间的方法就可以搞定。大家可以研究研究然后告诉我。

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

    1、Live your own, then enough. 2、Enjoy life, enjoy work. 新浪微博:http://weibo.com/zhouhongyu1989 欢迎围观~! 友情链接:http://zhouhongyu1989.blog.51cto.com/
  • 相关阅读:
    faster with MyISAM tables than with InnoDB or NDB tables
    w-BIG TABLE 1-toSMALLtable @-toMEMORY
    Indexing and Hashing
    MEMORY Storage Engine MEMORY Tables TEMPORARY TABLE max_heap_table_size
    controlling the variance of request response times and not just worrying about maximizing queries per second
    Variance
    Population Mean
    12.162s 1805.867s
    situations where MyISAM will be faster than InnoDB
    1920.154s 0.309s 30817
  • 原文地址:https://www.cnblogs.com/zhouhongyu1989/p/3780880.html
Copyright © 2011-2022 走看看