JS完成代码前最好对其做5件事


Posted in Javascript onApril 07, 2013

写在前面

我们不得面对这样一个事实:许多程序员不会规划他们的JS代码。我们经常快速写完代码、运行、提交。但当我们继续开发遇到变量和函数时不得不再次回头查看它们代表的含义,麻烦就从这里开始了。同样当我们在其他程序员手中获取脚本也会遇到类似的错误。因此,当我们说”this is done, I can go on”时最好对脚本做下列5件事情。

问题描述

现在我们想给每一个带有class属性为collapsible的DIV内部添加超链接A,来显示和隐藏DIV。

下面是用模块函数编写的实现代码:

var collapser = (function(){
var secs = document.getElementsByTagName('div');
for(var i=0;i<secs.length;i++){
if(secs[i].className.indexOf('collapsible')!==-1){
var p = document.createElement('p');
var a = document.createElement('a');
a.setAttribute('href','#');
a.onclick = function(){
var sec = this.parentNode.nextSibling;
if(sec.style.display === 'none'){
sec.style.display = 'block';
this.firstChild.nodeValue = 'collapse'
} else {
sec.style.display = 'none';
this.firstChild.nodeValue = 'expand'
}
return false;
};
a.appendChild(document.createTextNode('expand'));
p.appendChild(a);
secs[i].style.display = 'none';
secs[i].parentNode.insertBefore(p,secs[i]);
}
}
})();

上面的代码已经很准确的实现了我们想要的结果。但是我们还可以对上面的代码进一步的重构。

第一步:样式(CSS)与行为(JavaScript)分离

我们可以用添加一个CSS的class选择器来消除通过JS中设置的样式。这种现象在新手中经常遇到.

var collapser = (function(){
var secs = document.getElementsByTagName('div');
for(var i=0;i<secs.length;i++){
if(secs[i].className.indexOf('collapsible')!==-1){
secs[i].className += ' ' + 'collapsed';
var p = document.createElement('p');
var a = document.createElement('a');
a.setAttribute('href','#');
a.onclick = function(){
var sec = this.parentNode.nextSibling;
if(sec.className.indexOf('collapsed')!==-1){
sec.className = sec.className.replace(' collapsed','');
this.firstChild.nodeValue = 'collapse'
} else {
sec.className += ' ' + 'collapsed';
this.firstChild.nodeValue = 'expand'
}
return false;
}
a.appendChild(document.createTextNode('expand'));
p.appendChild(a);
secs[i].parentNode.insertBefore(p,secs[i]);
}
}
})();

第二步:对代码进一步性能优化

这里我们可以做两件事情:1、循环语句中secs的length属性可以用变量保存。2、为事件处理器创建重用的函数。好处是减少事件处理器数量,减少内存占用。

var collapser = (function(){
var secs = document.getElementsByTagName('div');
for(var i=0,j=secs.length;i<j;i++){
if(secs[i].className.indexOf('collapsible')!==-1){
secs[i].className += ' ' + 'collapsed';
var p = document.createElement('p');
var a = document.createElement('a');
a.setAttribute('href','#');
a.onclick = toggle;
a.appendChild(document.createTextNode('expand'));
p.appendChild(a);
secs[i].parentNode.insertBefore(p,secs[i]);
}
}
function toggle(){
var sec = this.parentNode.nextSibling;
if(sec.className.indexOf('collapsed')!==-1){
sec.className = sec.className.replace(' collapsed','');
this.firstChild.nodeValue = 'collapse'
} else {
sec.className += ' ' + 'collapsed';
this.firstChild.nodeValue = 'expand'
}
return false;
}
})();

第三步:添加配置对象

使用配置对象存放代码中的硬编码,如使用到的文本标签或自定义的属性名。有利于后续的维护。

var collapser = (function(){
var config = {
indicatorClass : 'collapsible',
collapsedClass : 'collapsed',
collapseLabel : 'collapse',
expandLabel : 'expand'
}
var secs = document.getElementsByTagName('div');
for(var i=0,j=secs.length;i<j;i++){
if(secs[i].className.indexOf(config.indicatorClass)!==-1){
secs[i].className += ' ' + config.collapsedClass;
var p = document.createElement('p');
var a = document.createElement('a');
a.setAttribute('href','#');
a.onclick = toggle;
a.appendChild(document.createTextNode(config.expandLabel));
p.appendChild(a);
secs[i].parentNode.insertBefore(p,secs[i]);
}
}
function toggle(){
var sec = this.parentNode.nextSibling;
if(sec.className.indexOf(config.collapsedClass)!==-1){
sec.className = sec.className.replace(' ' + config.collapsedClass,'');
this.firstChild.nodeValue = config.collapseLabel
} else {
sec.className += ' ' + config.collapsedClass;
this.firstChild.nodeValue = config.expandLabel
}
return false;
}
})();

第四步:为变量和函数起有含义的名字

var collapser = (function(){
var config = {
indicatorClass : 'collapsible',
collapsedClass : 'collapsed',
collapseLabel : 'collapse',
expandLabel : 'expand'
}
var sections = document.getElementsByTagName('div');
for(var i=0,j=sections.length;i<j;i++){
if(sections[i].className.indexOf(config.indicatorClass) !== -1){
sections[i].className += ' ' + config.collapsedClass;
var paragraph = document.createElement('p');
var trigger = document.createElement('a');
trigger.setAttribute('href','#');
trigger.onclick = toggleSection;
trigger.appendChild(document.createTextNode(config.expandLabel));
paragraph.appendChild(trigger);
sections[i].parentNode.insertBefore(paragraph,sections[i]);
}
}
function toggleSection(){
var section = this.parentNode.nextSibling;
if(section.className.indexOf(config.collapsedClass) !== -1){
section.className = section.className.replace(' ' + config.collapsedClass,'');
this.firstChild.nodeValue = config.collapseLabel
} else {
section.className += ' ' + config.collapsedClass;
this.firstChild.nodeValue = config.expandLabel
}
return false;
}
})();

第五步:添加必要的注释

// Collapse and expand section of the page with a certain class
// written by Christian Heilmann, 07/01/08
var collapser = (function(){
// Configuration, change CSS class names and labels here
var config = {
indicatorClass : 'collapsible',
collapsedClass : 'collapsed',
collapseLabel : 'collapse',
expandLabel : 'expand'
}
var sections = document.getElementsByTagName('div');
for(var i=0,j=sections.length;i<j;i++){
if(sections[i].className.indexOf(config.indicatorClass) !== -1){
sections[i].className += ' ' + config.collapsedClass;
var paragraph = document.createElement('p');
var trigger = document.createElement('a');
trigger.setAttribute('href','#');
trigger.onclick = toggleSection;
trigger.appendChild(document.createTextNode(config.expandLabel));
paragraph.appendChild(trigger);
sections[i].parentNode.insertBefore(paragraph,sections[i]);
}
}
function toggleSection(){
var section = this.parentNode.nextSibling;
if(section.className.indexOf(config.collapsedClass) !== -1){
section.className = section.className.replace(' ' + config.collapsedClass,'');
this.firstChild.nodeValue = config.collapseLabel
} else {
section.className += ' ' + config.collapsedClass;
this.firstChild.nodeValue = config.expandLabel
}
return false;
}
})();

 

Javascript 相关文章推荐
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
Mar 06 Javascript
学习YUI.Ext 第四天--对话框Dialog的使用
Mar 10 Javascript
JavaScript回调(callback)函数概念自我理解及示例
Jul 04 Javascript
jQuery动态改变图片显示大小(修改版)的实现思路及代码
Dec 24 Javascript
JS实现不使用图片仿Windows右键菜单效果代码
Oct 22 Javascript
基于JavaScript实现TAB标签效果
Jan 12 Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
Feb 27 Javascript
jQuery的文档处理程序详解
May 10 Javascript
微信小程序 数据遍历的实现
Apr 05 Javascript
vue2.0实现导航菜单切换效果
May 08 Javascript
JavaScript中为事件指定处理程序的五种方式分析
Jul 27 Javascript
基于JS实现父组件的请求服务过程解析
Oct 14 Javascript
有关于JS辅助函数inherit()的问题
Apr 07 #Javascript
运算符&amp;&amp;的三个不同层次
Apr 07 #Javascript
jquery实现excel导出的方法
Apr 04 #Javascript
关于jquery input textare 事件绑定及用法学习
Apr 03 #Javascript
Jquery实现弹出层分享微博插件具备动画效果
Apr 03 #Javascript
让低版本浏览器支持input的placeholder属性(js方法)
Apr 03 #Javascript
用Jquery重写windows.alert方法实现思路
Apr 03 #Javascript
You might like
用缓存实现静态页面的测试
2006/12/06 PHP
PHP 面向对象 final类与final方法
2010/05/05 PHP
PHP中使用匿名函数操作数据库的例子
2014/11/17 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
深入理解JavaScript系列(16) 闭包(Closures)
2012/04/12 Javascript
js中运算符&amp;&amp; 和 || 的使用记录
2014/08/21 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
2015/11/24 Javascript
AngularJs Modules详解及示例代码
2016/09/01 Javascript
JS实现页面载入时随机显示图片效果
2016/09/07 Javascript
鼠标经过出现气泡框的简单实例
2017/03/17 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
Node.js利用断言模块assert进行单元测试的方法
2017/09/28 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
js里面的变量范围分享
2020/07/18 Javascript
[02:25]DOTA2英雄基础教程 生死判决瘟疫法师
2013/12/06 DOTA
Python实现按当前日期(年、月、日)创建多级目录的方法
2018/04/26 Python
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
Python3.x+pyqtgraph实现数据可视化教程
2020/03/14 Python
python中def是做什么的
2020/06/10 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
英国顶尖手表珠宝品牌独家授权经销商:HS Johnson
2020/10/28 全球购物
通信工程毕业生求职信
2013/11/16 职场文书
简历中个人自我评价范文
2013/12/26 职场文书
小学生寒假家长评语
2014/04/16 职场文书
自愿离婚协议书范本
2015/01/26 职场文书
2015年学生会主席工作总结
2015/04/21 职场文书
《伯牙绝弦》教学反思
2016/02/16 职场文书
Python中glob库实现文件名的匹配
2021/06/18 Python
为什么RedisCluster设计成16384个槽
2021/09/25 Redis
Redis基本数据类型String常用操作命令
2022/06/01 Redis