在JavaScript对象内部还是外部拥有事件更好?
以为例,这里有一些简单的代码来生成一个在页面底部弹出的工具栏(我在这里使用jQuery):
tool_bar = {
show : function() {
$('#bottomBox')
.show()
.animate({ 'bottom' : '0' }, 700)
;
},
close : function() {
$('#bottomBox').hide();
}
};
$(function() {
$('#bottomBox span').click(function() {
tool_bar.hide();
});
});
window.onload = function() {
tool_bar.show();
};
在上面的例子中,我有tool_bar对象之外的事件。这个好还是那个好?
tool_bar = {
show : function() {
window.onload = function() {
$('#bottomBox')
.show()
.animate({ 'bottom' : '0' }, 700)
;
};
},
close : function() {
$('#bottomBox span').click(function() {
$('#bottomBox').hide();
});
}
};
$(function() {
tool_bar.close();
});
tool_bar.show();
应该提到,两者都有效。我只是想知道什么是更好的做法
我认为封装是一个值得追求的目标。这意味着您将对象的行为封装在该对象中。外部世界应该能够控制对象的安装或删除,并且能够控制客户端可能想要的任何其他行为,但是对象"内部"的行为应该完全在对象内部实现(至少对于默认行为)。
在您的具体情况下,我认为您应该允许外部代理安装或删除工具栏,但工具栏一旦安装后的操作应由工具栏本身处理。
我建议这样的实现具有以下优点:
- 所有行为被封装在对象
- 因为id被传递给构造函数,所以你可以有多个
- 对象负责管理它自己的事件处理程序,外部世界不需要知道这些。
-
show()
和hide()
有外部可用的方法。 - 你可以很容易地添加额外的行为
你可以这样实现一个工具栏:
var bottomToolbar = new tool_bar("bottomBox", true);
对象的代码如下:
// id is a required argument
// show is an optional argument (true means to show it as soon as possible)
var tool_bar = function(id, show) {
this.id = '#' + id;
this.show = function() {
$(this.id).show().animate({ 'bottom' : '0' }, 700);
};
this.hide = function() {
$(this.id).hide();
};
// .ready() code will either be fired immediately if document already ready
// or later when document is ready, so the code can be used either way
$(document).ready(function() {
if (show) {
this.show();
}
$(this.id + " span").click(function() {
this.hide();
});
});
}
如果你有声明或内置的东西-这并不重要,你在哪里重新定义它的值;
在你的例子中,两个代码的结果将是相同的。唯一的区别是,当你在函数或if或任何操作符之外声明:var x = "x";
时,它将成为一个全局变量,并立即赋值。您还可以将空变量var x;
声明为全局变量,并通过函数或任何操作符赋值,该值将保持在那里。由于window.onload
是一个全局对象的事件-这无关紧要,您将值赋给它。
我只会这样做:
$(function() {
var bottom = $('#bottomBox')
.show()
.animate({
'bottom': '0'
}, 700);
$('span', bottom).click(function() {
bottom.hide();
});
});
你也可以让它成为一个插件:
$.fn.toolbar = function(){
this
.show()
.animate({
'bottom': '0'
}, 700);
$('span', this).click(function() {
$(this).parent().hide();
});
return this;
}
$(function() {
$('#bottomBox').toolbar();
}
我倾向于将机制和策略分离,因此在您的示例中,我将以第一种方式构建代码。
第二种方法不是坏虽然,我只是a)调用函数像showOnLoad()
不同的东西,b)使用适当的事件注册(Guffa的答案可能是注册"on load"事件的最佳方法),而不是赋值给window.onload
。