以正确的姿势实现一棵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 ...
随机推荐
- 谈JS中的作用域链与原型链(1)
学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...
- 深入了解Unity中LineRenderer与TrailRenderer
LineRender和TrailRender是两个好东西,很多Unity拖尾特效都会使用到它们.一些简单的介绍可以参见官方的API文档.在这里探讨一下它们具体的渲染方式,而后给出一些Shader以便更 ...
- 在Eclipse上通过插件获取github上的spring源码
spring源码开始的时候是通过SVN来管理代码的,后来是转移到github上管理源码的,可以通过在github上直接下载spring的源码. 下面讲解如何通过在eclipse上的插件git来获取sp ...
- Linux实战教学笔记18:linux三剑客之awk精讲
Linux三剑客之awk精讲(基础与进阶) 标签(空格分隔): Linux实战教学笔记-陈思齐 快捷跳转目录: * 第1章:awk基础入门 * 1.1:awk简介 * 1.2:学完awk你可以掌握: ...
- 用DotRas来连接VPN网络
最近要用程序来不断的连接VPN(为什么要这样就不讨论了),开始用的是如下代码: public static bool ADSL() { bool flag = true; do { Console.W ...
- 3月题外:关于JS实现图片缩略图效果的一些小问题
由于3月可能要结束实习,所以应该不会有特别固定的主题,另外我会在月初陆续补上上个月的番外篇Projection和TMS,作为介绍性的内容对矢量切片部分进行补充,剩下时间不定期写一些杂烩. 最近两天在做 ...
- php+redis 简易的实现文章发布系统(用户投票系统)
/** * @data 文章发布 * 文章详情散列表中递增ID,讲文章发布者ID写入投票用户集合中,设置投票时间为一周 * 讲文章内容写入文章散列中,讲文章写入文章评分有序集合和文章发布有序集合中 * ...
- 【openstack N版】——云主机调整大小\冷迁移
一.先决条件 云主机冷迁移,即:将一台云主机从一个计算节点上,迁移到另外一个计算节点上.因为环境原因,所以我们需要准备两个计算节点. 1.1准备环境 在控制节点上,安装一个计算节点 #在控制节点安装n ...
- Python 3中字符串可以被改变吗?
Python 3中字符串可以被改变吗? 字符串有改变这个方法的:replace,比如: a = 'lkjhgfdsa' a.replace(') '123kjhgfdsa' #返回结果 从上面这个例子 ...
- 使用NTP协议服务器时间同步
NTP是用来使系统和一个精确的时间源保持时间同步的协议.建议大家在自己管理的网络中建立至少一台时间服务器来同步本地时间,这样可以使得在不同的系统上处理和收集日志和管理更加容易.我们分别从windows ...