使用自定义事件模拟domready事件(mootools)

时间:2010-05-06 19:43:32

标签: javascript events mootools

我需要只启动一次自定义事件,其功能类似于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);
});

1 个答案:

答案 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);

应该这样做。以下是两种测试方案:

  1. 资源尚未已加载,因此回调不应立即触发。

    window.addEvent('resourcesLoaded', function() { alert("should wait"); });

  2. 已加载资源 ,因此回调会立即触发。

    window.addEvent('resourcesLoaded', function() { alert("shouldn't wait"); });

  3. 我从MooTools源代码中获取了这个。这是它处理domready事件的方式。

    另外,在自己的自定义对象中实现事件同样容易,如果事件与DOM无关,则不必依赖窗口等DOM元素来完成工作。