I need to fire a one time only custom event that functions like the domready event, in that if new events are added after the event has occurred they are fired immediately.
This is for some code that cannot execute until certain data and resources are initialized, so I want to do something like this:
// 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
});
});
If开发者_开发知识库 possible I would like resourcesAreLoaded
to function like domready
, and execute the code immediately if the event has already fired:
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);
});
You would have to store the state of whether the custom event has been fired somewhere. One good place is the Element Store.
Custom events can have various properties defined. One useful property for this case is onAdd
which is basically a function that is called when you add that event to some DOM element by calling <element>.addEvent(<name>, <fn>)
. Your function for onAdd
will be called, and passed fn
as a parameter. Check if the event has already been fired, and if so, call fn
immediately, otherwise do nothing. Read up more about properties for custom events under the Hash: Element.Events section towards the bottom.
Element.Events.resourcesLoaded = {
onAdd: function(fn) {
if(window.retrieve('resourcesLoaded')) {
fn.call(this);
}
}
};
When you first fire the resourcesLoaded event, also set a boolean property for the window object. onAdd
can pull up this value from now on to see if event handlers should be fired immediately.
window.fireEvent('resourcesLoaded');
window.store('resourcesLoaded', true);
That should do it. Here are two test scenarios:
Resources have not been loaded, so the callback should not fire immediately.
window.addEvent('resourcesLoaded', function() { alert("should wait"); });
Resources have been loaded, so the callback fires immediately.
window.addEvent('resourcesLoaded', function() { alert("shouldn't wait"); });
I took this from the MooTools source code. This is how it handles the domready
event.
On a side note, it's equally easy to implement events inside your own custom objects and you don't have to rely on DOM elements such as window to do the job if the event has nothing to do with the DOM.
精彩评论