我们不得面对这样一个事实:许多程序员不会规划他们的 JS 代码。我们经常快速写完代码、运行、提交。但当我们继续开发遇到变量和函数时不得不再次回头查看它们代表的含义,麻烦就从这里开始了。
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
我们不得面对这样一个事实:许多程序员不会规划他们的 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 的 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;
- }
- })();
来源: