下拉树列表菜单选择器
来源:互联网 发布:淘宝直通车在哪里看 编辑:程序博客网 时间: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
- 下拉树列表菜单选择器
- 下拉树列表菜单选择器(2)
- Spinner下拉列表选择器
- bootstrap input 下拉树 下拉菜单 下拉列表
- popupMenu下拉菜单列表
- 导航列表下拉菜单
- 下拉列表 级联菜单操作
- [HTML] CSS 下拉列表菜单
- 简洁的下拉菜单列表
- 下拉列表菜单怎么做
- 导航菜单下拉列表 2级菜单
- 导航菜单动态显示下拉列表菜单
- 下拉列表,日期选择器,时间选择器,单项选择,多项选择
- 完全自定义sharepoint列表的下拉菜单
- 使用DIV+CSS实现下拉列表菜单
- JSwing实现 下拉列表形式菜单
- 无序列表实现导航下拉菜单
- VS2005列表框下拉菜单不显示
- 生成自动的主键值
- 隐藏UINavigationBar下面的一个像素的阴影
- IOS开发系列—Objective-C之内存管理详解
- ArrayAdapter(数组适配器)与SimpleAdapter(简单适配器)
- eclipse调试yarn
- 下拉树列表菜单选择器
- ACM比赛中通过freopen读取测试用例
- PAT (Advanced Level) 1082. Read Number in Chinese (25) 数字转汉字大写
- C#调用命令行返回参数方法
- Managing your Applications在同一个CI中设置多个application文件夹
- 控制台打印android信息
- win10卸载OneDrive
- 性能分析工具gprof介绍
- 【未测试】使用mysql-proxy 快速实现mysql 集群 读写分离