用 JavaScript 创建模块化的交互用户界面(2)
 
- UID
- 1066743
|

用 JavaScript 创建模块化的交互用户界面(2)
交互性的元素程序一般是通过将各功能块结合在一起而构建起来的。不同的程序员会有不同的实现方式,但作为一种规律,最好是采用多个小的功能块而不是少数几个大的功能块。每个小功能块应该实现一种功能并具有清楚的语义。
不过,在进行 GUI 编程时,这样的构建不太容易。好的 GUI 必须调整很多界面元素并将它们的行为结合起来形成一个能直观工作的整体行为。基于事件的系统通常都是由复杂的交换行为联合起来的回调集合。模块化的交互元素很难创建。
模块化的交互元素可切换代码就使用了模块化的交互元素。前面,我提到过在可切换系统内有两种主要的交互元素:拖动元素的突出显示和拖动到的目标的突出显示。在代码中,这两个元素的实现是分开的。
本例很好地展示了模块化处理交互性的技巧。正如可切换界面的描述中所提到的,这两个交互性元素常常缠结在一起。突出显示和突出显示的消失都是在一个鼠标操作中发生的,而且它们的发生都对应鼠标输入的不同方面。如果这两个元素是在一个代码片段中实现的,那么代码可能不太容易读懂,因为同时发生的事情很多。
拖动处理程序为了使 GUI 的实现模块化,我使用了拖动处理程序。这类似于内置在 GUI 系统的事件处理程序。虽然事件处理程序只处理某种单一事件,拖动处理程序却可以处理整个拖放过程。一个拖动处理程序可处理一系列事件而不只一个单一事件。下面是拖动处理程序的示例骨架,如清单 4 所示。
清单 4. 拖动处理程序的骨架1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {
start:
function( x, y ) {
// ...
},
move:
function( x, y ) {
// ...
},
done:
function() {
// ...
},
}
|
这个拖动处理程序是一个对象,具有三个方法:start、move 和 done。当初始化一个拖放动作时,调用 start 方法并传递给这次单击的对应坐标。当四处移动光标时,会反复调用 move 方法,然后同样被传递给光标当前对应的坐标。最后,当鼠标按钮释放后,就会调用 done 方法。
可切换系统同时使用了两个不同的拖动处理程序,这也让您能够干净地处理交互的两个不同方面,即便这两个方面具有复杂的关系。让其中的一个交互成为另一个交互的一部分并不合适。相反,应该能同时无缝地使用这两个交互。
rectangle_drag_handler这两个拖放处理程序的其中是 rectangle_drag_handler。此处理程序负责移动代表被拖动元素的透明矩形。清单 5 给出了这个 start 方法。
清单 5. rectangle_drag_handler 处理程序1
2
3
4
5
6
7
8
9
10
11
12
| function rectangle_drag_handler( target )
{
this.start = function( x, y ) {
this.cover = coveringDiv( target );
make_translucent( this.cover, .6 );
this.cover.style.backgroundColor = "#777";
dea( this.cover );
this.dragger = new dragger( this.cover, x, y );
};
// ...
}
|
start 方法创建这个透明矩形并将其传递给另一个称为 dragger 的对象。一个 dragger 就是一个对象,它能对应移动的光标移动 DOM 元素。可以将当前的光标的坐标传递给这个 dragger,它会更新所拖动的对象使其跟随光标的移动。
move 方法更新这个 dragger,如清单 6 所示。
清单 6. 更新 dragger1
2
3
| this.move = function( x, y ) {
this.dragger.update( x, y );
};
|
最后,done 方法(参见清单 7)删除这个透明矩形,因为拖放过程现在已经结束。
清单 7. rectangle_drag_handler 的 done 方法1
2
3
4
5
| this.move = function( x, y ) {
this.done = function() {
this.cover.parentNode.removeChild( this.cover );
};
}
|
|
|
|
|
|
|