下拉树列表菜单选择器

来源:互联网 发布:淘宝直通车在哪里看 编辑:程序博客网 时间:2024/06/08 15:10

虽然网上有许多的实现下拉树列表菜单的实现,但都是基于某一框架的,感觉使用起来过于复杂。

为了巩固学习的JS知识,于是尝试着自己写一个。


这个下拉树列表整体放置在一个div中。为了使其看起来和HTML自带的下拉列表类似,我选择了使用select标签,但一开始并不在其中嵌套option选项。(其实也可以用input自己实现一个,只不过我觉得这样用方便也美观......)

在select标签之后跟着一个div,主要用来放置目录列表,目录用ul标签嵌套的方式实现。该div使用绝对定位(这样在div显示的时候就不会占用文档空间),并且初始出于隐藏状态。

通过给select标签添加click事件监听,使目录div显示。

在选择目录后,生成一个option选项,将其加入到select中并将其选中,但option还是要隐藏,就可以在select中设置值了。(因为好像select不能直接通过给value赋值的方法赋值,所以只能采用这个折中的办法了。如果是用的input实现的,那么直接对其value赋值,就没这么麻烦。)


目前我只是完成一个粗略的结构,树形结构的展开和收缩功能也还没有加上,先写下这些东西记录下学习成果。随后逐步完善。

下面是代码

<!DOCTYPE html><html>    <head>        <title>Test2</title>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">    </head>    <body>        <div>TODO write content</div>
        <!-- 下来树列表 -->        <div style="width:200px;">            <select style="width:200px;padding: 0;margin: 0;" onclick="createTree(this)"></select>            <div  style="width:200px;padding-top:2px;margin: 0;background-color: #ccccff;display: none;overflow: auto;position: absolute;">                <ul>                    <li><a href="javascript:void(0);" title="A">A</a>                        <ul>                            <li><a href="javascript:void(0);" title="A1">A1</a></li>                            <li><a href="javascript:void(0);" title="A2">A2</a>                                <ul>                                    <li><a href="javascript:void(0);" title="AA2">AA2</a></li>                                    <li><a href="javascript:void(0);" title="AA3">AA3</a></li>                                </ul>                            </li>                        </ul>                    </li>                    <li><a href="javascript:void(0);" title="B">B</a>                        <ul>                            <li><a href="javascript:void(0);" title="B1">B1</a></li>                            <li><a href="javascript:void(0);" title="B2">B2</a></li>                        </ul>                    </li>                    <li><a href="javascript:void(0);" title="C">C</a></li>                </ul>            </div>        </div>    <script>        function createTree(component){                        //为select定义一个blur属性,用于标记select是否失去焦点            //这个属性将在select失去焦点时隐藏目录div是用到            //因为不能简单的设置当select失去焦点时就隐藏目录div            //这样的话点击目录时就会发生冲突,导致目录提前隐藏而没有选中值            component.blur = false;            component.addEventListener("blur",function(){                this.blur = true;            });                                    //获得目录列表,其中每两个标签之间有一个文本节点,所以select的父节点有5个子节点            //而包含列表的div是第四个节点            var parent = component.parentNode;            var treeMenu = parent.getElementsByTagName("div")[0];                        console.log("select is clicked "+component.blur);                                    //点击select时,列表是展开的就收缩列表,否则就展开列表            if(treeMenu.style.display === "none"){                treeMenu.style.display = "";                console.log("display");            }            else{                treeMenu.style.display = "none";                console.log("select hidden");            }                                    //获得每一个目录的link,并且给每一个link都绑定一个事件            //当该目录被选中时,就给select插入一个option,并且选中该option            //并且将该option设置为隐藏的,这样就设置了select的值            var menuLinks = treeMenu.getElementsByTagName("a");            //console.log(menuLinks[0].innerHTML);            for(var i=0;i<menuLinks.length;i++){                //console.log(menuLinks[i].innerHTML);               menuLinks[i].addEventListener("click",function(){                   console.log("Link is clicked");                    var text = this.innerHTML;                    var option = document.createElement("option");                    option.text = text;                    option.selected = true;                    option.style.display = "none";                    component.add(option,null);                    treeMenu.style.display = "none";                    console.log("link hidden");                });            }                        //给body绑定一个点击事件,这个事件用于检测鼠标是否在下拉树列表外进行了点击            //如果是,则要隐藏下拉树,相当于下拉树列表失去了焦点            //判断的方法是根据发生点击事件是鼠标的位置            document.body.addEventListener("click",function(event){                console.log("body is clicked");                    if(treeMenu.style.display !== "none"){                        /*console.log("top: "+treeMenu.offsetTop+" left: "+treeMenu.offsetLeft+                                " height: "+treeMenu.offsetHeight+" width: "+treeMenu.offsetWidth);                        console.log("eventX: "+event.clientX+" eventY: "+event.clientY);                        console.log(event.type);*/                        if((event.clientX<treeMenu.offsetLeft ||                           event.clientX>(treeMenu.offsetLeft+treeMenu.offsetWidth) ||                           event.clientY<treeMenu.offsetTop ||                           event.clientY>(treeMenu.offsetTop+treeMenu.offsetHeight))                           && component.blur){                           treeMenu.style.display = "none";                           console.log("body hidden");                        }                    }            });                        //给window绑定事件隐藏目录            //因为body并不一定能覆盖完整个浏览器窗口            //检测点击是否发生在body之外,如果是,就应该隐藏目录            //依然要检测select的blur属性,不然会有一个小bug            //在select边缘点击的时候,如果不检测select blur属性,会触发目录隐藏            window.addEventListener("click",function(event){               console.log("window is clicked");                //console.log(event.clientY);               if((event.clientX<document.body.offsetLeft ||                       event.clientX>(document.body.offsetLeft+document.body.offsetWidth) ||                       event.clientY<document.body.offsetTop ||                       event.clientY>(document.body.offsetTop+document.body.offsetHeight))                       && component.blur)                   if(treeMenu.style.display !== "none"){                       treeMenu.style.display = "none";                       console.log("widow hidden");                   }            });        }    </script>    </body></html>


0 0
原创粉丝点击