MVC模式(Model-View-Controller)常被用在Web程序中。如Struts框架就是一个基于MVC模式的Web框架。所谓MVC模式,就是将视图(也就是客户端代码,包括html、javascript等)和模型(和数据库及业务逻辑相关的Java代码)分开。并通过控制器将两者联系起来。这样做的好处可以使客户端开发人员和服务端开发人员的工作尽量分开,以使他们之间的干扰降到最低。Model和
虽然上面的代码从某种程度上达到了视图和逻辑分离的效果。但仍然有着一定的联系。我们可以看到,两个<input>标签的onclick事件不还是引用着fun1和fun2函数吗!其实美工人员是不关心这两个函数到底是做什么的,甚至并不需要知道它们的存在。那么是否有更高的方法呢?答案当然是肯定的,就是通过动态的方式指定onclick事件,而这一切美工人员是完全没有感觉的。 我们在文章的开头提到了MVC模式。其实在客户端也存在着一个MVC体系结构。我们可以将视图(V)看成是描述界面的html、css和javascript代码,而模型(M)可以看成是处理业务逻辑的javascript代码,而控制器(C)就是将这两类代码连接起来的代码(一般也是javascript代码)。 在本文中给出了一个小例子来演示一下如何通过动态的方法将V和M分离。这个例子是通过<div>实现的10个小方块,点击其中的某一个,会将相应的数字追加到下方的文本框架中,并且加入了一些用javascript实现的效果,如以一定间隔随机更新方块和数字的颜色,直接在文本框中输入数字后,相应的文本框和数字的颜色也会随机发生变化。界面效果如图1所示。
numberKeys.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="my.css"/>
<script type="text/javascript" src="addevents.js">
</script>
</head>
<body>
<input id ="changeColor" type="button" value="开始变换颜色" />
<br/><br/>
<div id ="nubmerKeys" class="numberKeys" >
</div>
<br/><br/>
<br/><br/>
<input id="numbers" type="text" size="80"/>
</body>
</html>
从上面的代码可以看出,除了一些html代码外,没有任何和业务逻辑有关的javascript代码。但使用<script>引用了一个叫addevents.js的文件。在这个文件中将为这个程序添加相应的逻辑代码,也就是说,这个文件相当于MVC中的M和C。onload事件完成的,代码如下:
window.onload = onLoad; // 为onload指定事件函数
function onLoad()
{
var text = document.getElementById("numbers");
if(text)
{
text.onkeyup = onKeyup; // 为文本框指定onkeyup事件
}
var button = document.getElementById("changeColor");
if(button)
{
button.onclick = stopAndStartTimer; // 为按钮指定onclick事件
}
addButton(); // 用于在<div>中加入10个<div>标签作为小方块,并指定onclick事件
}
addButton函数是如何实现的,代码如下:numberKeys的<span times="" new="" roman'"=""><div>标签,实现代码如下:
function getRandomArbitary(min, max)
{
return Math.round(Math.random() * (max - min) + min);
}
function getRandomColor()
{
var red = getRandomArbitary(0, 255).toString(16);
var green = getRandomArbitary(0, 255).toString(16);
var blue = getRandomArbitary(0, 255).toString(16);
if(red.length == 1) red = "0" + red;
if(green.length == 1) green = "0" + green;
if(blue.length == 1) blue = "0" + blue;
return "#" + red.toString(16) + green.toString(16) + blue.toString(16);
}
getRandomColor通过getRandomArbitary函数获得了三个十进制的随机数(0-255),并将其转换为16进制,并返回最终结果。buttonOnClick函数这个函数是<div>标签的onclick事件函数,实现代码如下:
function buttonOnClick()
{
var text = document.getElementById("numbers");
if(typeof this.innerText == "#ff0000")
text.value = text.value + this.textContent;
else
text.value = text.value + this.innerText;
this.style.backgroundColor = getRandomColor();
this.style.color = getRandomColor();
}
numbers文本框输入一个字符后,发生这个事件,实现代码如下:<span times="" new="" roman'"="">
function onKeyup()
{
var value = this.value;
if(value.length == 0) return;
var i = value.toString().substr(value.length - 1, 1);
if(isNaN(i) == false)
{
var div = getNumberKeysDiv();
if(div)
{
var button = div.childNodes[i];
button.style.backgroundColor = getRandomColor();
button.style.color = getRandomColor();
}
}
}
这个函数的实现代码也很简单。只是根据用户在文本框中输入的数字来找到相应的<div>标签,并再次随机变换<div>背景和数字的颜色。stopAndStartTimer函数这个函数是用来控制定时器的,如果启动定时器,浏览器会每隔3秒重新使<div>随机变化一次颜色。实现代码如下:
var time;
function stopAndStartTimer()
{
if(this.value.toString().indexOf("停止",0) > -1)
{
this.value = "开始变换颜色";
clearInterval(time);
}
else
{
this.value = "停止变换颜色";
time = setInterval(onLoad, 3000);
}
}
从上面给出的代码可以看出,在View层,除了<script>引用了一个javascript文件外,并未涉及任何和逻辑有关的代码。而设计界面的美工也并不知道开发人员会为<div>及其他的按钮和文本框添加什么动作。而美工要做的是调整和界面有关的东西,如颜色,位置,分割等。只要使用<script>引用了这个js文件,就可以很容易加入相应的动作,而要将这些动作去掉,删除或注释掉这个<script>标签即可。 尤其要提一下<div>标签,美工在设计界面时可以向这个<div>标签添加任何子元素。而在加入addevents.js后,程序会自动将由美工向<div>标签中的加入的内容都删除,而加入由业务逻辑需要的元素。这样美工用来设计界面的元素就不会影响开发人员需要加入的和业务逻辑有关的元素了。 根据上面的代码不难看出,numberKeys.html属于视图层,所有的事件函数属性模型层,而其他的javascript代码都属性控制器(Controller)。