基于事件委托实现无限级折叠菜单(42)

事件委托(事件代理)

 

    一个容器中,很多后代元素的点击行为都要处理一些事情,之前的思路是把需要操作的元素一一获取,然后再一一做事件绑定,在不同的方法中完成不同的需求;现在不用了,基于事件的冒泡传播,我们可以只给容器的CLICK绑定一个方法,这样不管以后点击的是容器中的哪一个后代元素,都会通过事件的冒泡传播机制,把容器的CLICK行为触发,把绑定的方法执行,我们在方法执行的时候,根据事件对象中的事件源(EV.TARGET)来做不同的业务处理即可,这种机制即使事件委托机制

    1.容器中很多后代元素的某个行为要进行操作,委托给容器处理是不错的选择

    2.元素是动态绑定的

    3.需求是除了某某某,剩下的操作都是干同样的事情(此时把点击行为的操作委托给BODY,事件源是某某做什么,不是统一做什么)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>折叠菜单</title>
    <link rel="stylesheet" href="css/reset.min.css">
    <style>
        html, body {
            height: 100%;
            overflow: hidden;
        }

        .menuBox {
            width: 300px;
            height: 100%;
            overflow: auto;
            /*CSS3中新增的背景颜色渐变*/
            background: -webkit-linear-gradient(top left, lightblue, lightcyan, lightpink, lightgoldenrodyellow);
        }

        .menuBox li {
            position: relative;
        }

        .menuBox li span {
            margin-left: 20px;
            line-height: 30px;
            font-size: 14px;
        }

        .menuBox li em {
            position: absolute;
            left: 0;
            top: 7px;
            width: 16px;
            height: 16px;
            background: url("img/icon.png") no-repeat;
        }

        .menuBox li em.plus {
            background-position: -59px -28px;
        }

        .menuBox li em.minus {
            background-position: -42px -29px;
        }

        .menuBox .level1 {
            margin-left: 10px;
        }

        .menuBox .level2 {
            margin-left: 20px;
        }

        .menuBox .level3 {
            margin-left: 30px;
        }

        .menuBox .level4 {
            margin-left: 40px;
        }

        /*CSS3中的NOT伪类:除了XXX*/
        .menuBox ul:not(.level1) {
            display: none;
        }
    </style>
</head>
<body>
<section class="menuBox">
    <ul class="level1">
        <li>
            <!--每个LI中必有SPAN,如果有下一级,再有EM和UL即可-->
            <!--plus:+  minus:- -->
            <em class="plus"></em><span>产品技术部</span>
            <ul class="level2">
                <li><span>产品小组</span></li>
                <li>
                    <em class="plus"></em><span>UI小组</span>
                    <ul class="level3">
                        <li><span>UI设计师</span></li>
                        <li><span>UE体验师</span></li>
                    </ul>
                </li>
                <li>
                    <em class="plus"></em><span>开发小组</span>
                    <ul class="level3">
                        <li>
                            <em class="plus"></em><span>前端开发</span>
                            <ul class="level4">
                                <li><span>传统前端开发</span></li>
                                <li><span>VR/AI开发</span></li>
                                <li><span>NATIVE-APP开发</span></li>
                                <li><span>NODE开发</span></li>
                            </ul>
                        </li>
                        <li><span>后台开发</span></li>
                        <li><span>服务器开发</span></li>
                        <li><span>公共技术研发团队</span></li>
                    </ul>
                </li>
                <li>
                    <em class="plus"></em><span>测试小组</span>
                    <ul class="level3">
                        <li><span>黑盒测试</span></li>
                        <li><span>白盒测试</span></li>
                    </ul>
                </li>
                <li><span>运维小组</span></li>
            </ul>
        </li>
        <li>
            <!--每个LI中必有SPAN,如果有下一级,再有EM和UL即可-->
            <!--plus:+  minus:- -->
            <em class="plus"></em><span>产品技术部</span>
            <ul class="level2">
                <li><span>产品小组</span></li>
                <li>
                    <em class="plus"></em><span>UI小组</span>
                    <ul class="level3">
                        <li><span>UI设计师</span></li>
                        <li><span>UE体验师</span></li>
                    </ul>
                </li>
                <li>
                    <em class="plus"></em><span>开发小组</span>
                    <ul class="level3">
                        <li>
                            <em class="plus"></em><span>前端开发</span>
                            <ul class="level4">
                                <li><span>传统前端开发</span></li>
                                <li><span>VR/AI开发</span></li>
                                <li><span>NATIVE-APP开发</span></li>
                                <li><span>NODE开发</span></li>
                            </ul>
                        </li>
                        <li><span>后台开发</span></li>
                        <li><span>服务器开发</span></li>
                        <li><span>公共技术研发团队</span></li>
                    </ul>
                </li>
                <li><span>测试小组</span></li>
                <li><span>运维小组</span></li>
            </ul>
        </li>
        <li>
            <!--每个LI中必有SPAN,如果有下一级,再有EM和UL即可-->
            <!--plus:+  minus:- -->
            <em class="plus"></em><span>产品技术部</span>
            <ul class="level2">
                <li><span>产品小组</span></li>
                <li>
                    <em class="plus"></em><span>UI小组</span>
                    <ul class="level3">
                        <li><span>UI设计师</span></li>
                        <li><span>UE体验师</span></li>
                    </ul>
                </li>
                <li>
                    <em class="plus"></em><span>开发小组</span>
                    <ul class="level3">
                        <li>
                            <em class="plus"></em><span>前端开发</span>
                            <ul class="level4">
                                <li><span>传统前端开发</span></li>
                                <li><span>VR/AI开发</span></li>
                                <li><span>NATIVE-APP开发</span></li>
                                <li><span>NODE开发</span></li>
                            </ul>
                        </li>
                        <li><span>后台开发</span></li>
                        <li><span>服务器开发</span></li>
                        <li><span>公共技术研发团队</span></li>
                    </ul>
                </li>
                <li><span>测试小组</span></li>
                <li><span>运维小组</span></li>
            </ul>
        </li>
    </ul>
</section>

<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/tree.js"></script>
</body>
</html>
let $menuBox = $('.menuBox');
$menuBox.on('click', function (ev) {
    let target = ev.target,
        $target = $(target),
        tarTag = target.tagName;

    //=>合并事件源:点击的是EM,我们让TARGRT也等于它弟弟SPAN,此时TARGET只有SPAN我们才处理,统一基于SPAN位置为参照即可
    if (tarTag === 'EM') {
        $target = $target.next();
        target = $target[0];
        tarTag = target.tagName;
    }

    //=>只有事件源是SPAN我们才会处理
    if (tarTag === 'SPAN') {
        let $ul = $target.next('ul'),
            $em = $target.prev('em');
        //=>基于JQ获取的结果一般都是JQ对象,即使没有获取到元素也是一个LENGTH为零的空对象,而不是NULL,所以 if($ul){...} 这样算存在不行 (“如果没有下级结构,我们什么都不做处理,有下一级结构在控制显示和隐藏即可”)
        if ($ul.length === 0) return;

        //=>EM的样式类名:如果是PLUS(加号),说明当前是折叠的,我们应当让其展开,反之让其折叠起来
        let promise = new Promise(resolve => {
            $ul.stop().slideToggle(200, () => {
                resolve();
            });
        });
        if ($em.hasClass('plus')) {
            $em.addClass('minus').removeClass('plus');
            // $ul.stop().slideDown(200);
        } else {
            $em.addClass('plus').removeClass('minus');
            // $ul.stop().slideUp(200);
            //=>外层级收起,里面的小层级也都应该收起
            promise.then(() => {
                $ul.find('em').removeClass('minus').addClass('plus');
                $ul.find('ul').css('display', 'none');
            });
        }
    }
});

 效果展示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值