以正确的姿势实现一棵JavaScript菜单树
菜单树是常见的前端特效, 一般长下面这样

还有各种形态的变种, 有长这样的

也有长这样的

尽管这些菜单的相貌都不尽相同, 在功能实现的本质上却都是相同的。实现程序的大致流程如下
读取服务器端的菜单数据
将数据转换成html菜单结构
为菜单结构绑定各种交互事件,如展开、关闭等。
然而, 随着需求的变化, 菜单往往会需要一些基础之外的功能, 比如说添加菜单项、删除菜单项、修改菜单名、拖拽子菜单至其它父菜单项之下等, 实现这些额外的功能将增加菜单制作的难度。就拿添加菜单项这个功能来讲, 添加菜单项事件中代码的常规实现流程如下
为菜单的html结构添加一个菜单项元素结点并指定节点的名称
将菜单新节点数据添加至初始化菜单html结构的数据中
将新菜单的数据通过ajax发送至服务器端持久存储
删除菜单的流程亦如此
删除菜单中菜单项html节点
删除初始化菜单的数据中对应的数据项
将菜单的标识通过ajax发送至执行删除操作的服务器端程序
这种做法不能说有问题, 但是并不完美。 尤其是对于添加菜单项功能, 当菜单项添加完成时还需要为新添加的菜单节点绑定对应的事件 , 这不但使原本只需要3步的添加操作变成了4步, 还导致了代码逻辑的不一致、程序实现的复杂化,因为绑定事件这一步是重复的,在初始化菜单的时候执行过这项操作。 如何避免此类情况的出现呢? 其实并不难,换种思路即可。
拿添加菜单项这个功能来说, 我们完全可以使用3步操作来替代上面的4步实现操作
直接在菜单的数据源中添加菜单的数据项
重新渲染(初始化)
将数据发送至服务器端持久保存
这样做程序逻辑是不是清晰了很多, 而且渲染这个操作之前就已经实现了, 现在只需要拿来用就可以了,因此看似3步的操作实质上只有2步而已, 整个过程得到了极大的简单。 而且这种做法也适用于删除和修改两个功能项
删除操作
删除菜单数据中要删除的菜单数据项,并且重新初始化菜单
将数据保存至服务器
修改操作
修改菜单数据中的需要修改的数据项,并且重新初始化菜单
将数据保存至服务器
如你所见, 所有对菜单的修改操作只需要针对菜单的数据源就可以了, 对菜单html元素结构的操作都可以省略掉,因为这些功能都已经包含在初始化菜单的过程中了,完全没有多此一举的必要再去调用一遍。
这种做法看起来有一个坏处, 就是程序比较耗费性能, 因为每次对菜单的改动都会触发一次重新初始化菜单的操作。 事实上不必为此担忧, 首先现代的浏览器对于界面的渲染优化已至极致, 其次执行一次菜单初始化操作所占用的用户计算机资源消耗量几乎可以忽略不计, 对于用户体验更是完全没有丝毫影响 , 用户的感观能力远没有灵敏到可以感知如此微乎其微的变化。反而实现菜单代码逻辑复杂度的降低为程序员带来的好处却非常明显, 简化逻辑的好处从开发维护时间成本到程序员的编码体验都会有不同程度的体现。
前端和后端不同, 前端程序消耗的资源和运行程序的机器总是一对一的, 因此性能消耗只要不是太过分, 对于用户的影响不会很明显 ; 而后端程序消耗的资源和运行程序的机器往往是多对一的, 只有拼命的压榨程序的资源消耗才能降低服务器的负荷。
所以, 在开发前端程序的时候, 完全可以牺牲部分性能以达到程序逻辑的简化目的, 这是值得的。
以正确的姿势实现一棵JavaScript菜单树的更多相关文章
- xpath轴的正确使用姿势
网上看了许多关于轴的介绍,只介绍了语法,而没有明说具体实际中该怎么使用,百思不得其解. 背景--python中使用xpath: ----------------------------------- ...
- 高版本jquery尤其是1.10.2的版本设置input radio设置值的最正确的姿势。
$("input:radio[name="analyshowtype"]").attr("checked",false); $(" ...
- NSnotificationCenter 正确使用姿势, removeObject 探索
最近在做平板的过程中,发现了一些很不规范的代码.偶然修复支付bug的时候,看到其他项目代码,使用通知的地方没有移除,我以为我这个模块的支付闪退是因为他通知没有移除的缘故.而在debug和看了具体的代码 ...
- 微信H5中静默登录及非静默登录的正确使用姿势
在微信中打开网页且需要调用微信登录接口时,微信官方给我们提供了两种登录调用方式:静默登录和非静默登录:但是官方文档中却没有说明在何种情况下使用静默登录,何种情况下使用非静默登录,所以在这里,我想将之前 ...
- Java日志正确使用姿势
前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中“尽情”的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的bug发生,作为一名 ...
- MongoDB系列:五、MongoDB Driver使用正确的姿势连接复制集
MongoDB复制集(Replica Set)通过存储多份数据副本来保证数据的高可靠,通过自动的主备切换机制来保证服务的高可用.但需要注意的时,连接副本集的姿势如果不对,服务高可用将不复存在. 使用复 ...
- 基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势)
基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势) 前言 前几天对Apollo配置中心的demo进行一个部署试用,现公司已决定使用,这两天进行分布式部署的时候 ...
- 玩转java多线程(wait和notifyAll的正确使用姿势)
转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...
- Gradle的依赖方式——Lombok在Gradle中的正确配置姿势
写过java的都知道,lombok几乎在项目中处于不可或缺的一部分,但是lombok在Gradle的项目中配置并非人人都知道. 很多人在项目依赖中直接这样写 1 compile "org.p ...
随机推荐
- Java中abstract和interface的区别
abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和inte ...
- Android Realm数据库使用指南
Android Realm数据库使用指南 Realm数据库, 目前有Java, Objective‑C, React Native, Swift, Xamarin的几种实现, 是一套用来取代SQLit ...
- Tomcat使用Memcached Session Manager管理Session
Tomcat使用Memcached Session Manager管理Session 废话不多说,直接进入主题.项目使用阿里云负载均衡+ECS服务器集群进行部署,Tomcat使用8.5版本.阿里云负载 ...
- 计算机存储负数以及int转byte时-128的出现
我们看下面这段代码 输出的结果的是128,这个没什么疑问 但是当我们不改变数值仅仅加了一个强制转换后 这时我们会发现结果会变成负的128.这时候我们就要怀疑了,为什么会出现这样的结果呢? 对于这个问题 ...
- MyBatis从入门到放弃一:从SqlSession实现增删改查
前言 开博客这是第一次写系列文章,从内心上讲是有点担心自己写不好,写不全,毕竟是作为java/mybatis学习的过程想把学习的路线和遇到的问题都总结下来,也让知识点在脑海里能形成一个体系. 开发环境 ...
- x86主机搭建家庭智能路由系统 ---- 设计篇
组件简介 Proxmox: 基于Debian的虚拟化系统,支持OpenVZ和KVM. pfSense: 基于FreeBSD的开源路由系统. FreeNAS: 开源NAS系统. shadowsocks: ...
- 代写编程的作业、笔试题、课程设计,包括但不限于C/C++/Python
代写编程作业/笔试题/课程设计,包括但不限于C/C++/Python 先写代码再给钱,不要任何定金!价钱公道,具体见图,诚信第一! (截止2016-11-22已接12单,顺利完成!后文有成功交付的聊天 ...
- ci 框架发送邮箱
定义数据 $config = array( 'protocol' =>'smtp', 'smtp_host'=>'ssl://smtp.163.com', 'smtp_u ...
- Python全栈开发——Linux命令学习
Linux -- 一切皆文件 pwd: 查看当前所在目录 '/' :根目录 cd : 切换目录 eg.cd / 切换到根目录 ls:查看当前根目录下有几块盘.几个文件 ls -l:查看详细信 ...
- NOI全国赛(2001)--食物链
今天写了道并查集的题,看来并查集的题刷少了,,,,,用法好神奇啊!!!开三倍并查集 用i表示自己,i+n存天敌,i+2*n存可以克制de,再逻辑判断一下即可. 所以,要意识到并查集的分类处理可以开不同 ...