第五步:轻松维护(Easing Maintenance)
脚本功能齐全,分离式而且无懈可击。真正的问题是,现在并不方便维护。
脚本应用的最大的问题大概是,并不是所有的维护者都懂 JavaScript 和愿意在你的脚本中寻找需要修改的部分。
为了避免维护者做这些,最安全的方法就是把脚本和 CSS 中使用的命名和 ID 从你的脚本功能中分离出来。此外,从使用的脚本中分离出文本标签也是个好点子,因为他们可能会改变。例如,当脚本使用其他语言本地化时。
工具方法的复用
第一件要做的事情就是,从主要脚本中分离出其他脚本也可以再用的工具函数。这也许是大部分 JavaScript 库的开始。
tools.js:
/* 辅助方法 */ tools = { addEvent:function( obj, type, fn ) { if ( obj.attachEvent ) { obj['e'+type+fn] = fn; obj[type+fn] = function(){ obj['e'+type+fn]( window.event ); } obj.attachEvent( ‘on’+type, obj[type+fn] ); } else obj.addEventListener( type, fn, false ); }, removeClass:function(o,c){ var rep=o.className.match(’ ‘+c)?’ ‘+c:c; o.className=o.className.replace(rep,”); }, addClass:function(o,c){ var test = new RegExp(”(^|\\s)” + c + “(\\s|$)”).test(o.className); if(!test){o.className+=o.className?’ ‘+c:c;} }, cancelClick:function(e){ if (window.event){ window.event.cancelBubble = true; window.event.returnValue = false; } if (e && e.stopPropagation && e.preventDefault){ e.stopPropagation(); e.preventDefault(); } } } |
CSS 的 class 和 ID —— 外观
下一步要做的是,分离外观的 class 和 ID 到一个单独的包含文件。保证他们在 slideshow 命名空间里是安全的,因为其他脚本不太可能用到他们。也不会妨碍写一个简短的说明注释。
CSS.js" target=_blank>slideshow-CSS.js:
文本标签(Text labels)—— 解释给终端用户
最后但不是最不重要的,让我们将文本标签放到一个单独的包含文件,再次使用 slideshow 命名空间。
slideshow-labels.js:
改变的主要脚本
然后,我们需要修改主要脚本使用此信息,而不是依赖嵌入式的数据。没有太多的改变,很容易用搜索加替换就能做到。
slideshow.js:
slideshow = { current:0, init:function(){ if(document.getElementById && document.createTextNode){ var list =document.getElementById(slideshow.CSS.showID); if(list){ slideshow.items = list.getElementsByTagName('li'); slideshow.all = slideshow.items.length; if(slideshow.all > 1){ tools.addClass(list, slideshow.CSS.dynamicClass); slideshow.createNav(list); } } slideshow.show(); } }, createNav:function(o){ var p = document.createElement('p'); tools.addClass(p, slideshow.CSS.slideNavigationClass); slideshow.prev = document.createElement('a'); slideshow.prev.setAttribute('href', '#'); var templabel = document.createTextNode(slideshow.labels.previous); slideshow.prev.appendChild(templabel); tools.addEvent(slideshow.prev, 'click', slideshow.show); p.appendChild(slideshow.prev); slideshow.count = document.createElement('span'); templabel =document.createTextNode((slideshow.current+1) + slideshow.labels.counterDivider + slideshow.all); slideshow.count.appendChild(templabel); p.appendChild(slideshow.count); slideshow.next = document.createElement('a'); slideshow.next.setAttribute('href', '#'); var templabel = document.createTextNode( slideshow.labels.next); slideshow.next.appendChild(templabel); tools.addEvent(slideshow.next, 'click', slideshow.show); p.appendChild(slideshow.next); o.parentNode.insertBefore(p, o); }, show:function(e){ if(this === slideshow.next || this === slideshow.prev){ tools.removeClass(slideshow.items[slideshow.current], slideshow.CSS.currentClass); var addto = this === slideshow.next ? 1 : -1; slideshow.current = slideshow.current + addto; if(slideshow.current < 0){ slideshow.current = (slideshow.all-1); } if(slideshow.current > slideshow.all-1){ slideshow.current = 0; } } var templabel = document.createTextNode((slideshow.current+1) + slideshow.labels.counterDivider + slideshow.all); slideshow.count.replaceChild(templabel, slideshow.count.firstChild); tools.addClass(slideshow.items[slideshow.current], slideshow.CSS.currentClass); tools.cancelClick(e); } } tools.addEvent(window,’load’,slideshow.init);
|
这些所有文件是确保将来维护者不用麻烦你就可以使用你的脚本工作所需要的。文件名应该很明显,是什么就是什么,并能随着时间的推移,成为一个标准的脚本。
演示:http://www.blueidea.com/articleimg/2008/06/5895/index.html
|
slideshow.labels = { /* 这些都是幻灯片效果中使用到文本标签。 你可以在这里修改他们中的任何一个。 务必请使用引号包围名称。 最后一个结尾不用逗号。 */
previous : '<<', next : '>>’, counterDivider : ‘ of ‘ } |
|
slideshow.CSS = { /* 这些都是幻灯片效果中使用到的 classe 和 ID。 你可以在这里修改他们中的任何一个。 务必请使用引号包围名称,用逗号结尾(除了最后一个)。 */
showID :'slideshow', dynamicClass :'js', slideNavigationClass :'slidenav', currentClass :'current' }
|
|
slideshow = { current:0, // 当前幻灯片编码 init:function(){ // 初始化和设置事件处理函数 }, show:function(e){ // 事件监听器 }, addEvent:function( obj, type, fn ) { if ( obj.attachEvent ) { obj['e'+type+fn] = fn; obj[type+fn] = function(){ obj['e'+type+fn]( window.event ); } obj.attachEvent(’on’+type, obj[type+fn] ); } else obj.addEventListener( type, fn, false ); }, removeClass:function(o,c){ var rep=o.className.match(’ ‘+c)?’ ‘+c:c; o.className=o.className.replace(rep,”); }, addClass:function(o,c){ var test = new RegExp(”(^|\\s)”+c+”(\\s|$)”).test(o.className); if(!test){o.className+=o.className?’ ‘+c:c;} }, cancelClick:function(e){ if (window.event){ window.event.cancelBubble = true; window.event.returnValue = false; } if (e && e.stopPropagation && e.preventDefault){ e.stopPropagation(); e.preventDefault(); } } }
slideshow.addEvent(window,’load’,slideshow.init);
|