我需要只启动一次自定义事件,其功能类似于domready事件,因为如果在事件发生后添加了新事件,则会立即触发它们。
这是针对某些代码在初始化某些数据和资源之前无法执行的,所以我想做这样的事情:
// I am including a script (loadResources.js) to load data and other resources,
// when loadResources.js is done doing it's thing it will fire resourcesAreLoaded with:
window.fireEvent('resourcesAreLoaded');
window.addEvent('resourcesAreLoaded', function() {
// this is fine
});
$('mybutton').addEvent('click', function() {
window.addEvent('resourcesAreLoaded', function() {
// this is not fine, because resourcesAreLoaded has already fired
// by the time the button is clicked
});
});
如果可能,我希望resourcesAreLoaded
的功能类似于domready
,并在事件已经触发时立即执行代码:
window.addEvent('testIsReady', function() {
alert('firing test');
});
window.fireEvent('testIsReady');
window.addEvent('test', function() {
// this will never execute unless I call fireEvent('testIsReady') again
alert('test 2');
});
window.addEvent('domready', function() {
alert('domready is firing');
});
window.addEvent('domready', function() {
setTimeout(function() {
alert('domready has already fired, so this is executed immediately');
}, 500);
});
答案 0 :(得分:5)
您必须存储自定义事件是否已在某处触发的状态。一个好地方是Element Store。
自定义事件可以定义各种属性。这种情况的一个有用属性是onAdd
,它基本上是一个通过调用<element>.addEvent(<name>, <fn>)
将该事件添加到某个DOM元素时调用的函数。将调用onAdd
的函数,并将fn
作为参数传递。检查事件是否已被触发,如果是,请立即调用fn
,否则不执行任何操作。阅读更多关于Hash: Element.Events部分下方自定义事件属性的信息。
Element.Events.resourcesLoaded = {
onAdd: function(fn) {
if(window.retrieve('resourcesLoaded')) {
fn.call(this);
}
}
};
首次触发resourcesLoaded事件时,还要为窗口对象设置布尔属性。 onAdd
从现在开始可以提取此值,以查看是否应立即触发事件处理程序。
window.fireEvent('resourcesLoaded');
window.store('resourcesLoaded', true);
应该这样做。以下是两种测试方案:
资源尚未已加载,因此回调不应立即触发。
window.addEvent('resourcesLoaded', function() { alert("should wait"); });
已加载资源 ,因此回调会立即触发。
window.addEvent('resourcesLoaded', function() { alert("shouldn't wait"); });
我从MooTools源代码中获取了这个。这是它处理domready
事件的方式。
另外,在自己的自定义对象中实现事件同样容易,如果事件与DOM无关,则不必依赖窗口等DOM元素来完成工作。