既然对于Web层的诸多页面冗余,我们提出了重新整理的想法,那么这种思想也必然应该是贯彻始终的,换言之,在开发过程中应该“绷紧这根弦”,敏感的不要放过任何有可能改善重复的机会。对于JSP页面,我们可以在确定框架之后,采用include机制,而对于JSP页面以外的其他元素呢?比如JavaScritp,比如CSS。
一个典型的例子是用JavaScript实现的鼠标悬浮于文本输入框之上时控件风格的改变。以前的做法是,要在每一个页面的首部先定义一段JavaScript代码:
function mouseOverInput() {
this.className = “focus";
}
function mouseOutInput() {
this.className = “";
}
这里的focus定义于一个外部的css文件中。然后,在文本输入框出现的地方,我们需要加上这么一句:
<input type="text” onmouseover="mouseOverInput();” onmouseout="mouseOutInput();” />
随着时间的推移,duplication不断重现,最后就会发现,有的页面中只有function定义,而没有对function的引用。事实上,上述功能在“要求所有文本输入框都遵循该规则”的前提下,完全可以有更为优雅而不致错误的做法。我们可以将下列JavaScript代码作为公共部分独立于所有页面:
/// general.js
// set onload handler
if(document.all)
window.onload=addEvent;
function addEvent(){
aTags = document.getElementsByTagName("INPUT");
for (var i=0; i<atags .length; i++)
with(aTags[i]) {
if (type!="text")
continue;
// set onmouseout handler for text box
onmouseout = function() {
className = ‘’;
}
// set onmouseover handler for text box
onmouseover = function() {
className = ‘focus’;
}
}
}
这样,引用该js文件的页面,其中包含的所有文本输入框无须额外设置,都将自动获得前述界面效果。
<input type="text">
因而也不用担心漏写onmouseover和onmouseout消息响应函数的调用了。除了需要在文件首部包含一行引入该js文件的JavaScript代码外,页面内部对其他事情一概不知。
上述解决方法还有一个缺陷,假如我们希望在页面加载时做一些自定义的初始化操作,我们也许会在页面里定义自己的myInit函数,然后将其设置为onload消息的处理函数。比如:
<script src="general.js"></script>
<script>
function myInit() {
alert(’init’);
}
</script>
<body onload="myInit">
</body> >
此时,general.js中的addEvent函数将不起作用。为了解决这个问题,我们可以做一个简单的约定:在general.js中定义一个dummy myInit,它什么事情都不做,在addEvent中会将其作为callback函数进行调用。
function addEvent(){
// …
myInit();
}
function myInit() {}
如果我们需要在本页面内定义自己的初始化行为,则可以在引入general.js之后再行定制myInit。并且,我们不用在body标记中声明onload属性了。当然,如果你希望强行“注销”addEvent的功能,也可以这么做:
<body onload="">
</body>