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 相关文章推荐
关于实现代码语法标亮 dp.SyntaxHighlighter
Feb 02 Javascript
jQuery的实现原理的模拟代码 -3 事件处理
Aug 03 Javascript
基于jquery封装的一个js分页
Nov 15 Javascript
通过Javascript读取本地Excel文件内容的代码示例
Apr 08 Javascript
JS正则表达式比较常见用法
Jan 26 Javascript
Javascript日期格式化format函数的使用方法
Aug 30 Javascript
微信小程序 Page()函数详解
Oct 17 Javascript
jQuery实现立体式数字滚动条增加效果
Dec 21 Javascript
JS跨域请求外部服务器的资源
Feb 06 Javascript
webpack实践之DLLPlugin 和 DLLReferencePlugin的使用教程
Jun 10 Javascript
layui prompt 设置允许空白提交的方法
Sep 24 Javascript
vue v-model的用法解析
Oct 19 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
通过php快速统计某个数据库中每张表的数据量
2012/09/04 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
Apache服务器下防止图片盗链的办法
2015/07/06 PHP
基于PHP实现商品成交时发送短信功能
2016/05/11 PHP
利用PHP如何写APP接口详解
2016/08/23 PHP
基于jQuery的弹出消息插件 DivAlert之旅(一)
2010/04/01 Javascript
jquery 插件学习(二)
2012/08/06 Javascript
JS跨域代码片段
2012/08/30 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
IE8中使用javascript动态加载CSS的解决方法
2014/06/17 Javascript
jQuery实现信息提示框(带有圆角框与动画)效果
2015/08/07 Javascript
JS实现的论坛Ajax打分效果完整实例
2015/10/31 Javascript
jQuery入门之层次选择器实例简析
2015/12/11 Javascript
Uploadify上传文件方法
2016/03/16 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
JavaScript 绘制饼图的示例
2021/02/19 Javascript
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
python实现封装得到virustotal扫描结果
2014/10/05 Python
Python二叉树的定义及常用遍历算法分析
2017/11/24 Python
Windows下python3.6.4安装教程
2018/07/31 Python
对python打乱数据集中X,y标签对的方法详解
2018/12/14 Python
CSS3条纹背景制作的实战攻略
2016/05/31 HTML / CSS
canvas实现按住鼠标移动绘制出轨迹的示例代码
2018/02/05 HTML / CSS
ECCO爱步美国官网:来自丹麦的鞋履品牌
2016/11/23 全球购物
洲际酒店集团英国官网:IHG英国
2019/07/10 全球购物
营销总监岗位职责范本
2014/02/26 职场文书
护理专业毕业生自我鉴定总结
2014/03/24 职场文书
主管竞聘书范文
2014/03/31 职场文书
小学生国庆演讲稿
2014/09/05 职场文书
党员查摆问题及整改措施
2014/10/10 职场文书
瘦西湖导游词
2015/02/03 职场文书
初中团支书竞选稿
2015/11/21 职场文书
Nginx反向代理配置的全过程记录
2021/06/22 Servers
Hive导入csv文件示例
2022/06/25 数据库