Facade(外观)模式
Facade 模式为更大的代码体提供了一个方便的更高层次接口,能够隐蔽其底层的真实复杂性。可以把它想象成是简化 API 来展示给其他开发人员,通常都是可以提高可用性
Facade 是一种结构型模式,在 jQuery 等 JavaScript 库中进程可以看到,尽管一个实现可能支持具有广泛行为的方法,但却只有一个“外观”或这些方法的有限抽象能够提供给公总使用。
每当使用 jQuery 的$(el).css() 或 $(el).animate()方法时,实际上我们时在使用 Facade:一种更简单的公有接口,是我们不必手动在 jQuery 核心中调用更多内部很多方法以便实现某些行为。这也避免了手动与 DOM API 交互并维护状态变量的需要
jQuery 核心方法应该被认为时中间抽象。对于开发人员来说,更直接的事是 DOM API,外观可以使 jQuery 库很容易使用
这是一个未优化的代码示例,但在这里,我们使用 Facade 来简化用于监听跨浏览器事件的接口。为此,创建一个可以用于某些代码的通用方法,该代码的任务是检查特性的存在,以便能够提供一个安全的、跨浏览器的兼容解决方案。
1 | var addMyEvent = function(el, ev, fn) { |
我们都很熟悉的jQuery的$(document).ready(..), 采用了类似的方式。在内部,它实际上是使用了一个被称为bindReady()的方法,它是这样做的:
1 | // jQuery 1.72 |
DOMContentLoaded 事件
1
2
3
4
5
6
7
8
9 DOMContentLoaded不同的浏览器对其支持不同,所以在实现的时候我们需要做不同浏览器的兼容。
1)支持DOMContentLoaded事件的,就使用DOMContentLoaded事件;
2)IE6、IE7不支持DOMContentLoaded,但它支持onreadystatechange事件,该事件的目的是提供与文档或元素的加载状态有关的信息。
3)更低的ie还有个特有的方法doScroll, 通过间隔调用:document.documentElement.doScroll("left");
可以检测DOM是否加载完成。 当页面未加载完成时,该方法会报错,直到doScroll不再报错时,就代表DOM加载完成了。该方法更接近DOMContentLoaded的实现。
Facade不是必须单独使用。它们也可以与其他模式集成,如Module模式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 var module = (function() {
var _private = {
i: 5,
get: function() {
console.log("current value:" + this.i);
},
set: function(val) {
this.i = val;
},
run: function() {
console.log("running");
},
jump: function() {
console.log("jumping")
}
};
return {
facade: function(args) {
_private.set(args.val);
_private.get();
if(args.run) {
_private.run();
}
}
};
})()
module.facade({
run: true,
val: 20,
})
在这个示例中,调用module.facade()实际上会在该模块中触发一系列的私有行为,但用户不会接触到。我们让facade变成一个不需要关注实现细节,而且更容易使用的一个特性。
当使用Facade模式时,要试着了解涉及的任何性能成本,并确认是否值得抽象。