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 相关文章推荐
extjs 学习笔记(一) 一些基础知识
Oct 13 Javascript
jQuery函数的等价原生函数代码示例
May 27 Javascript
浅析tr的隐藏和显示问题
Mar 05 Javascript
AngularJS 实现弹性盒子布局的方法
Aug 30 Javascript
微信小程序 富文本转文本实例详解
Oct 24 Javascript
jQuery使用ajax方法解析返回的json数据功能示例
Jan 10 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
Feb 15 Javascript
详解Node.js项目APM监控之New Relic
May 12 Javascript
详解通过JSON数据使用VUE.JS
May 26 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
Nov 21 Javascript
Vue两种组件类型:递归组件和动态组件的用法
Aug 06 Javascript
JS实现简易日历效果
Jan 25 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 Token(令牌)设计
2008/03/15 PHP
PHP统计目录下的文件总数及代码行数(去除注释及空行)
2011/01/17 PHP
PHP 循环删除无限分类子节点的实现代码
2013/06/21 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
2014/09/22 PHP
CodeIgniter配置之autoload.php自动加载用法分析
2016/01/20 PHP
js键盘上下左右键怎么触发function(实例讲解)
2013/12/14 Javascript
js读写cookie实现一个底部广告浮层效果的两种方法
2013/12/29 Javascript
JQuery中操作Css样式的方法
2014/02/12 Javascript
JQuery调用WebServices的方法和4个实例
2014/05/06 Javascript
JavaScript中实现异步编程模式的4种方法
2014/09/24 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
2015/05/20 Javascript
非常棒的jQuery图片轮播效果
2016/04/17 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
jQuery实现将div中滚动条滚动到指定位置的方法
2016/08/10 Javascript
AngularJs+Bootstrap实现漂亮的计算器
2017/08/10 Javascript
VSCode中如何利用d.ts文件进行js智能提示
2018/04/13 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
javascript中undefined的本质解析
2019/07/31 Javascript
vue+koa2搭建mock数据环境的详细教程
2020/05/18 Javascript
Vue将props值实时传递 并可修改的操作
2020/08/09 Javascript
vue-video-player视频播放器使用配置详解
2020/10/23 Javascript
浅谈django三种缓存模式的使用及注意点
2018/09/30 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
python实现网站微信登录的示例代码
2019/09/18 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
快速解决pymongo操作mongodb的时区问题
2020/12/05 Python
python爬虫基础之urllib的使用
2020/12/31 Python
css3 伪元素和伪类选择器详解
2014/09/04 HTML / CSS
Python里面search()和match()的区别
2016/09/21 面试题
工程管理造价应届生求职信
2013/11/13 职场文书
初三学生个人自我评定
2014/04/06 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
设计专业毕业生求职信
2014/06/25 职场文书
大学生活动总结模板
2014/07/02 职场文书
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android