编程挑战--下拉菜单
最近有一个叫慕客网的学习平台,现在很火。课程后面一般都会留有一道小题目,用来检测小伙伴们的学习结果。我看到有一个课程还不错,后面也跟了很多回复,不过感觉代码质量都不高,这可能和课程定位有关,如果你有信心写的更好,不妨来挑战一下。有兴趣的同学可以参考下面的链接:
课程地址:http://www.imooc.com/code/3631
我把题目要求再贴一下:
编程挑战
小伙伴们,根据所学知识,实现下图所示的菜单效果,实现点击菜单中的向下三角展开菜单,点击页面空白处收起菜单,按下键盘上的向上、向下方向键可以选中对应的选项,鼠标点击或按下回车键将当前高亮的选项内容设为菜单的标题
效果图: 在线演示:http://runjs.cn/detail/eoc1gtit
初始:
点击出现:
点击之后:
要求就这么多,我看到小伙伴们实现的都差不多,无非就是一个一个的循环邦定事件。完全是按提示做的,没有自己的创新。
下面我贴下自己的代码:
/** * 下拉菜单 * @param {string} id 节点#ID */ function Selecter (id) { var parent = document.getElementById(id), nodes = parent.children; this.parent = parent; this.title = nodes[0]; this.menu = nodes[1]; this.init(); } /** * 初始化 */ Selecter.prototype.init = function(){ var doc = document; this.selected = null; this.maxLen = this.menu.children.length; doc.addEventListener('click',this,false); doc.addEventListener('keydown',this,false); this.menu.addEventListener('mouseover',this,false); this.menu.addEventListener('mouseout',this,false); } /** * 事件处理 * @param {object} event 事件对象 */ Selecter.prototype.handleEvent = function(event){ var target = event.target || event.srcElement; switch(target.nodeName){ //点击三角时 case 'CITE': this.menuShow(); break; // 滑过滑过、离开、点击每个选项时 case 'A': this.removeLight(); this.selected = target; this.menuUpdate(); this.hightLight(); if(event.type=='click'){ this.menuHide(); } break; // 点击页面空白处时 case 'HTML': this.menuHide(); break; //键盘操作 default: this.keydown(event.keyCode); break; } return } /** * 更新菜单值 */ Selecter.prototype.menuUpdate = function(){ this.title.innerHTML = this.selected.innerHTML; } /** * 高亮选中项 */ Selecter.prototype.hightLight = function(){ if(this.selected){ this.selected.style.backgroundColor = 'gray'; } } /** * 移除高亮 */ Selecter.prototype.removeLight = function(){ if(this.selected){ this.selected.style.backgroundColor = 'white'; } } /** * 显示菜单项 */ Selecter.prototype.menuShow = function(){ this.menu.style.display = 'block'; this.hightLight(); } /** * 隐藏菜单项 */ Selecter.prototype.menuHide = function(){ this.menu.style.display = 'none'; } /** * 取下一项 */ Selecter.prototype.next= function(){ var target = this.selected; var index = target ? target.getAttribute('selectid')-1 : -1; this.removeLight(); index = ++index % this.maxLen; this.selected = this.menu.children[index].children[0]; this.hightLight(); } /** * 取上一项 */ Selecter.prototype.prev = function(){ var target = this.selected; var index = target ? target.getAttribute('selectid')-1 : 1; this.removeLight(); index = --index < 0 ? 0 : index; this.selected = this.menu.children[index].children[0]; this.hightLight(); } /** * 键盘操作 * @param {number} code ASSIC码 */ Selecter.prototype.keydown = function(code){ switch(code){ case 40: //down this.next(); break; case 38://up this.prev(); break; case 13: this.menuUpdate(); this.menuHide(); break; default: break; } } //调用 window.onload=function(){ var menu = new Selecter('divselect'); }
我是以对象的方式进行编写的,这样写的好处有:
1:对于调用者来说,不需要关心下拉框内部的节点和实现逻辑。只要传入一个id就可以了。
2: 整个下拉菜单看成是一个对象,每次对菜单进行什么操作,在对象内部都可以进行存储。避免进行不必要的节点查询操作。
3: 事件邦在根节点上,通过冒泡进行监听,即节省代码又可以有效提高性能。
4:代码按功能进行编写,结构清晰,扩展和维护方便。
以上就是王婆卖瓜,欢迎吐糟。
标签:
javascript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?