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 相关文章推荐
js将iframe中控件的值传到主页面控件中的实现方法
Mar 11 Javascript
node.js中的socket.io入门实例
Apr 26 Javascript
Javascript核心读书有感之语言核心
Feb 01 Javascript
JQuery日历插件My97DatePicker日期范围限制
Jan 20 Javascript
JavaScript中ES6 Babel正确安装过程
Jul 18 Javascript
AngularJS中关于ng-class指令的几种实现方式详解
Sep 17 Javascript
bootstrap提示标签、提示框实现代码
Dec 28 Javascript
JavaScript表单即时验证 验证不成功不能提交
Aug 31 Javascript
vue watch监听对象及对应值的变化详解
Feb 24 Javascript
详解jQuery中的easyui
Sep 02 jQuery
JavaScript实现小球沿正弦曲线运动
Sep 07 Javascript
详解vue-router导航守卫
Jan 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实现从ftp服务器上下载文件树到本地电脑的程序
2009/02/10 PHP
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
在Yii2中使用Pjax导致Yii2内联脚本载入失败的原因分析
2016/03/06 PHP
YII Framework框架教程之使用YIIC快速创建YII应用详解
2016/03/15 PHP
Symfony2中被遗弃的getRequest()方法分析
2016/03/17 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
JavaScript中的函数模式详解
2015/02/11 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
JQuery中Text方法用法实例分析
2015/05/18 Javascript
javascript如何操作HTML下拉列表标签
2015/08/20 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
jQuery拖拽通过八个点改变div大小
2020/11/29 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
基于vue cli 通过命令行传参实现多环境配置
2018/07/12 Javascript
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
在Vue项目中取消ESLint代码检测的步骤讲解
2019/01/27 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
2020/10/31 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
Python3基础之输入和输出实例分析
2014/08/18 Python
Python中的探索性数据分析(功能式)
2017/12/22 Python
Python实现的凯撒密码算法示例
2018/04/12 Python
Python列表list常用内建函数实例小结
2019/10/22 Python
django model object序列化实例
2020/03/13 Python
Python视频编辑库MoviePy的使用
2020/04/01 Python
解决keras backend 越跑越慢问题
2020/06/18 Python
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
英国高级健康和美容产品零售商:Life and Looks
2019/08/01 全球购物
什么是Remote Module
2016/06/10 面试题
商场经理竞聘演讲稿
2014/01/01 职场文书
搞笑婚礼主持词
2014/03/13 职场文书
精彩广告词大全
2014/03/19 职场文书
校庆团日活动总结
2014/08/28 职场文书
群众路线党员个人整改措施
2014/10/27 职场文书
深入理解go缓存库freecache的使用
2022/02/15 Golang