美文网首页填坑之路
填坑之路:jquery事件绑定

填坑之路:jquery事件绑定

作者: 哦啦吧啦丶 | 来源:发表于2017-04-25 23:43 被阅读15次

    最近边上班边做毕设(感觉自己马上要接到离职通知书了),好久没写原生js,遇到一个问题,前端请求返回了一个部门Json数组,大概长这样:

    var json = [{
                    dId: 1,
                    level: 0,
                    dName: '研发中心',
                    pid: ''
                }, {
                    dId: 101,
                    level: 1,
                    dName: '部门1',
                    pid: 1
                }, {
                    dId: 102,
                    level: 1,
                    dName: '部门2',
                    pid: 1
                }, {
                    dId: 103,
                    level: 1,
                    dName: '部门3',
                    pid: 1
                }, {
                    dId: 10101,
                    level: 2,
                    dName: '小组1',
                    pid: 101
                },{
                    dId: 10102,
                    level: 2,
                    dName: '小组2',
                    pid: 101
                },{
                    dId: 10201,
                    level: 2,
                    dName: '小组1',
                    pid: 102
                },{
                    dId: 10202,
                    level: 2,
                    dName: '小组2',
                    pid: 102
                },{
                    dId: 10203,
                    level: 2,
                    dName: '小组3',
                    pid: 102
                }];
    

    我需要把它渲染成树结构,这他么居然困扰了我一早上(一边做项目组任务,一遍切换做毕设,强行解释成精力没办法集中),晚上回来,认真写写就出来了;

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <script type="text/javascript" src="js/jquery-2.1.4.min.js" ></script>
            <title>department</title>
        </head>
        <body>
            <div id="Department"></div>
            <script type="text/javascript">
    
            $(function() {
                $("#Department").on('click','span',function(){
                    alert($(this).siblings("input").val())
                })
    
               //模拟了后台返回的部门json数组
                var json = [{
                    dId: 1,
                    level: 0,
                    dName: '中心',
                    pid: ''
                }, {
                    dId: 101,
                    level: 1,
                    dName: '部门1',
                    pid: 1
                }, {
                    dId: 102,
                    level: 1,
                    dName: '部门2',
                    pid: 1
                }, {
                    dId: 103,
                    level: 1,
                    dName: '部门3',
                    pid: 1
                }, {
                    dId: 10101,
                    level: 2,
                    dName: '小组1',
                    pid: 101
                },{
                    dId: 10102,
                    level: 2,
                    dName: '小组2',
                    pid: 101
                },{
                    dId: 10201,
                    level: 2,
                    dName: '小组1',
                    pid: 102
                },{
                    dId: 10202,
                    level: 2,
                    dName: '小组2',
                    pid: 102
                },{
                    dId: 10203,
                    level: 2,
                    dName: '小组3',
                    pid: 102
                }];
                // 注意我放了事先把 department-div 给加上了,后面写好了它的内容,直接 append 进来就好,当然也可以直接写在后面;
                var html = '<div>'
                        +'<div class="center-part">'+json[0].dName+'</div>'
                        +'<input value="'+json[0].dId+'" type="hidden"/>'
                        +'</div>'
                        +'<div class="department-part">'
                        +'</div>';
    
                // 先把最高权级的中心给渲染了(这里我在设计表结构的时候偷懒了,直接默认第一个为最高级了,所以这里就直接取了,注意:一个好的习惯就是先清空内容 empty() 再 append);
                $("#Department").empty().append(html);
    
                // 早上问题就出在这了,这个department是要一直循环添加的,所以得写在第一层 for 循环的外面;
                var departmentHtml = '';
                for(var i=1;i<json.length;i++){
                    // 偷懒again,直接在表结构中说明了它的级别,而且更偷懒的是,我指定了一共就三级,hahahahhahahaha
                    if (json[i].level ===1) {
                        // 这里少了div的结尾,因为还要判断是否存在子级的组,所以封尾放在后面了;
                        departmentHtml +='<div class="department">'
                                        +'<span>'+json[i].dName+'</span>'   
                                        +'<input value="'+json[i].dId+'" type="hidden"/>';
    
                        // 因为可能要添加多个组,所以头尾拆开;
                        var groupHead = '![](img/more.svg)' 
                                        +'<div class="group-part">';
                        // groupHtml 放在for循环的外面,可以保证每次执行完内层循环后其内容被清空,这样就可以做下一个部门内小组的添加了;                                    
                        var groupHtml = '';
    
                        for (var j= 1 ; j<json.length ; j++) {
                            // 判断父级(这是表机构设计,返回的json数组格式的局限,只能这么判断了)
                            if(json[j].pid === json[i].dId) {
                                groupHtml += '<div class="group">'
                                            +'<span>'+json[j].dName+'</span>'   
                                            +'<input value="'+json[j].dId+'" type="hidden"/>'
                                            +'</div>';
                            }
                        }
                        // groupHtml 不为空表示有子节点组级的存在,加上头尾,否则直接给department封尾
                        if (groupHtml !== '') {
                            groupHtml = groupHead + groupHtml + '</div>';
                            departmentHtml = departmentHtml + groupHtml + "</div>";
                        } else {
                            departmentHtml = departmentHtml + groupHtml + "</div>";
                        }
                    }
                }
                 // 结束最外层的for循环,直接append到部门div中;
                $(".department-part").empty().append(departmentHtml);
                
            })  
            </script>
        </body>
    </html>
    

    结果如下(旁边的图标是用来点击显隐组级部门用的,测试而已,没写样式,不要太在意):


    结果图!

    你可能已经发现了,上面还有一个代码没写注释,我把它拎出来:

    $("#Department").on('click','span',function(){
        alert($(this).siblings("input").val())
    })
    

    这就是jquery的比较常用的事件绑定,用关键字 on(当然以前也有 bind、live、delelgate 之类的),

    $(selector).on(event,childselector,data,function)
    

    参照我的写法,可以比较清楚的理解各个参数的意思,

    • event:必需项,这可以指定一个事件:‘click’,也可以指定一组事件:‘click dbclick mouseout’;
    • childselector:可选;表示需要添加事件处理程序的元素,一般为selector的子元素,没填则表示事件绑定在 $(selector) 上;
    • data:可选;需要传递的参数;
    • function:必需项;当绑定事件发生时,需要执行的函数;

    既然已经知道了这个事件绑定了,那么什么时候用它呢?个人觉得平时给dom写事件,最好都采用绑定这样比较稳妥,因为我们知道,事件绑定的好处就是像无赖般一旦定义了,就是死死地绑在指定选择器对应的dom上了,不关你是原本就存在于document中的 还是后面 append进去的,只要你满足绑定条件,事件一定会触发。

    回到之前的代码,我的写法是获取我点击的部门所对应的dId(因为我后面要根据这个id发请求去获取用户列表),那么当我把这段代码写在 script 的最前面的时候,我就得采用如上写法,用事件绑定到 #Department 下的 span节点上(因为页面渲染是按照文档顺序的,这时候下面进行的 append 等操作还没被渲染,所以页面文档树中还没有这些dom,如果没采用事件绑定 事件是肯定不会生效的)。
    但如果我们把这段代码写在 append的后面,也就是在确保你要绑定事件的 append 已经都结束了,页面文档树长已经渲染了这些 dom 了,那么你就可以不用采用事件绑定了 :

    $("#Department").find("span").on('click',function(){
        alert($(this).siblings("input").val())
    })
    

    这样也可以实现同样的功能的。
    当然,个人建议是,在确认绑定事件不会影响后续操作时,能绑定的尽量去绑定吧。

    相关文章

      网友评论

        本文标题:填坑之路:jquery事件绑定

        本文链接:https://www.haomeiwen.com/subject/wkubzttx.html