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

写在前面


我们不得面对这样一个事实:许多程序员不会规划他们的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;
}
})();

(0)

相关推荐

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

    写在前面 我们不得面对这样一个事实:许多程序员不会规划他们的JS代码.我们经常快速写完代码.运行.提交.但当我们继续开发遇到变量和函数时不得不再次回头查看它们代表的含义,麻烦就从这里开始了.同样当我们在其他程序员手中获取脚本也会遇到类似的错误.因此,当我们说"this is done, I can go on"时最好对脚本做下列5件事情. 问题描述 现在我们想给每一个带有class属性为collapsible的DIV内部添加超链接A,来显示和隐藏DIV. 下面是用模块函数编写的实现代码

  • THREE.JS入门教程(5)你应当知道的十件事

    Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 嗨,这是我的第一篇关于如何写出好的代码的文章.和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习.在过去的几个月中,我在canvas标签上花了很多时间,我想如果把这段时间学到的关于WebGL和JavaScript的小技巧都写下来,

  • 女人为你的男人做33件事

    在网上看到下面的这些,其实反过来,男人以女人,何尝不应该这样呢? 而有些我就没做得很好,所以才弄成今天这个样子,唉!!! 1.他去上班前,帮他穿上外套: 2.他出差前,给他一个吻: 3.他去朋友那之前,嘱咐他早点回来:  4.天气不好要记得让他带伞:  5.超过正常时间没有回来要打个电话安心,并且注意不要使用太指责的口吻:  6.他的朋友来家里,对他的朋友要客气: 7.在他的朋友面前或是公共场合面前,多给他一点面子: 8.在和他的熟人,包括他的同事.朋友.家人谈话时,适当地说说他的好处:  9.

  • js中的前绑定和后绑定详解

    其主要意思就是看我有没有用过前绑定,即Dom树中的某些元素在还没有创建出来时,就指定该类型的元素一出生就应该拥有的某些事件.在实际开发过程中经常会涉及到前绑定和后绑定.顾名思义,前绑定--还未出生即绑定了某些事件,后绑定--出生后才会绑定的某些事件.下面,通过一个简单的例子进行阐述,以供大家参考,并对各个方法进行比较:页面元素: 复制代码 代码如下: <div id="main"> <a href="#">aaaaaaaaaaaaaaaaaa

  • js原生代码实现轮播图的实例讲解

    轮播图是现在网站网页上最常见的效果之一,对于轮播图的功能,要求不同,效果也不同.我们见过很多通过不同的方式,实现这一效果,但是有很多比较麻烦,而且不容易理解,兼容性也不好.在这里分享一下,用js原生代码,实现轮播图的常见效果!思路比较清晰,而且可重复性高,也几乎包含了现在网页上轮播实现的所有效果! 一.现在我们来看看它是什么样的效果,截一张图给大家看: 二.无论我们做什么特效,都要记住一个原则,先写静态的代码,再做动态的处理! 我们的轮播静态效果用html和css来实现: 1.为了代码的规范性,

  • “增强js程序代码的健壮性”之我见大量示例代码

    在书写和使用js程序的过程中,我们经常会遇到各种各样的错误,对于一个依赖于浏览器的语言,我们很难完全去控制其在任何时刻都正确无误的运行.但是我们仍需做出自己努力取增强我们书写的js程序代码的健壮性和安全性,尽可能减少错误的出现概率. 以下为本人在学习js过程总结的几点关于增强js程序的健壮性的心得,如果您觉得对你有一点的价值,那我就达到自己的目的了,如果你觉得没有什么意义,请您也不必扔砖头,谢谢. (1)对于必要的参数要判断是否被正确的传入. 代码示例: [Ctrl+A 全选 注:如需引入外部J

  • JS异步代码单元测试之神奇的Promise

    前言 写这篇文章的起因是在写单元测试时,做形如下测试时 new Promise((resolve, reject) => reject(1)).then().catch(err => { console.log(err) }) async function jestTest () { await Promise.resolve().then() console.log('这个时候catch预期已经被调用,且输出日志') } jestTest() 无法使用await将测试代码恰好阻塞到catch

  • JS封装转换前后端接口数据格式工具函数下划线<=>大写

    目录 一.前言 二.思路 三.代码 四.效果 结语 一.前言 这段时间接近年底,公司的业务也不是很繁忙,有些闲暇的时间,就模仿ruoyi写一个后台系统,技术栈前端是react18,后端为koa2: 在一个接口返回数据的过程中,遇到一个问题,就是后端数据保存到数据库中的命名标准是下划线,而前端的这边的命名标准是驼峰命名,所以如果直接将从数据库的数据返回给前端,便非常不优雅,网上想直接找工具包,也没找到合适的,故而自己手写了一个,如果有同样需求的小伙伴们,可以直接拿去用. 二.思路 一般后端返回给前

  • angular.js分页代码的实例

    对于大多数web应用来说显示项目列表是一种很常见的任务.通常情况下,我们的数据会比较多,无法很好地显示在单个页面中.在这种情况下,我们需要把数据以页的方式来展示,同时带有转到上一页和下一页的功能.现在在学习angular,使用angularjs 分页,基于 directive 实现,样式使用的 bootstrap,直接在 html代码中加入 标签即可调用. 先来看下效果图 实例代码 app.directive('pagePagination', function(){ return { rest

  • js获取当前日期前七天的方法

    本文实例讲述了js获取当前日期前七天的方法.分享给大家供大家参考.具体如下: //设置日期,当前日期的前七天 var myDate = new Date(); //获取今天日期 myDate.setDate(myDate.getDate() - 7); var dateArray = []; var dateTemp; var flag = 1; for (var i = 0; i < 7; i++) { dateTemp = (myDate.getMonth()+1)+"-"+

随机推荐