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 相关文章推荐
常用一些Javascript判断函数
Aug 14 Javascript
jquery队列函数用法实例
Dec 16 Javascript
JQuery中DOM加载与事件执行实例分析
Jun 13 Javascript
javascript框架设计之类工厂
Jun 23 Javascript
jQuery Validate插件实现表单验证
Aug 19 Javascript
使用jQuery和ajax代替iframe的方法(详解)
Apr 12 jQuery
微信小程序实现手指触摸画板
Jul 09 Javascript
vue操作下拉选择器获取选择的数据的id方法
Aug 24 Javascript
JavaScript 复制对象与Object.assign方法无法实现深复制
Nov 02 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
May 01 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
Aug 17 Javascript
js 数据类型判断的方法
Dec 03 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
推荐几部必看的DC动画电影
2020/03/03 欧美动漫
无限级别菜单的实现
2006/10/09 PHP
PHP仿盗链代码
2012/06/03 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
php 表单提交大量数据发生丢失的解决方法
2014/03/03 PHP
jQuery+php简单实现全选删除的方法
2016/11/28 PHP
php 输出缓冲 Output Control用法实例详解
2020/03/03 PHP
总结一些js自定义的函数
2006/08/05 Javascript
jquery动画2.元素坐标动画效果(创建一个图片走廊)
2012/08/24 Javascript
JS实现图片翻书效果示例代码
2013/09/09 Javascript
调整小数的格式保留小数点后两位
2014/05/14 Javascript
bootstrap改变按钮加载状态
2014/12/01 Javascript
js操作XML文件的实现方法兼容IE与FireFox
2016/06/25 Javascript
html5+canvas实现支持触屏的签名插件教程
2017/05/08 Javascript
详解VueJs中的V-bind指令
2018/05/03 Javascript
详解vue项目中调用百度地图API使用方法
2019/04/25 Javascript
移动端手指操控左右滑动的菜单
2019/09/08 Javascript
element-ui tooltip修改背景颜色和箭头颜色的实现
2019/12/16 Javascript
Vue-router 报错NavigationDuplicated的解决方法
2020/03/31 Javascript
element日历calendar组件上月、今天、下月、日历块点击事件及模板源码
2020/07/27 Javascript
vue+vant 上传图片需要注意的地方
2021/01/03 Vue.js
[48:53]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第一场
2014/05/26 DOTA
Python合并多个装饰器小技巧
2015/04/28 Python
详细解读Python中的__init__()方法
2015/05/02 Python
在Python的Django框架中使用通用视图的方法
2015/07/21 Python
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
Django框架多表查询实例分析
2018/07/04 Python
python生成以及打开json、csv和txt文件的实例
2018/11/16 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
使用pyhon绘图比较两个手机屏幕大小(实例代码)
2020/01/03 Python
澳大利亚小众服装品牌:Maurie & Eve
2018/03/27 全球购物
BISSELL官网:北美吸尘器第一品牌
2019/03/14 全球购物
置业顾问岗位职责
2014/03/02 职场文书
读书活动总结
2014/04/28 职场文书
环保建议书600字
2014/05/14 职场文书
店长岗位职责
2015/02/11 职场文书