Implementing a chain in mootools is relatively simple, but incorporating the Chain class as a mixin can be more complex.
Usually, the focus is on chaining Fx-based classes and methods rather than synchronous ones. For instance, if you have a tween effect with link: chain
activated, you can use .chain(function() {})
to execute another action afterwards.
The callChain example works fine independently but lacks timing control options.
Another approach involves a linear timeline. In this scenario, each callback is executed at a specific time interval after the previous one. If you link actions together so that each step triggers the next one, you must consider the waiting time between actions carefully.
An alternative method is to defer the actions from the beginning.
Here's an attempt to streamline the process: http://jsfiddle.net/dimitar/mpzzq/
(function(){
Chain.implement({
slowChain: function(duration){
// console.log(duration);
this.callChain.delay(duration === null ? 500 : duration, this);
}
});
var db = $(document.body);
var fixBody = function(cn, delay) {
console.log(arguments);
db.addClass(cn);
console.log(cn, delay);
if (this.$chain.length) {
this.slowChain(delay || 0);
}
};
var myChain = new Chain(),
funcs = [{
fn: fixBody,
args: ["load"],
delay: 1980
}, {
fn: fixBody,
args: ["load-two"],
delay: 700
}, {
fn: fixBody,
args: ["load-three"],
delay: 2000
}, {
fn: fixBody,
args: ["load-four"],
delay: 0
}];
myChain.chain(
funcs.map(function(el) {
el.args.push(el.delay);
return el.fn.bind.apply(el.fn, [myChain].concat(el.args));
})
);
document.getElement("button").addEvents({
click: function() {
myChain.slowChain(20);
}
});
})();
In the array of objects within 'funcs', I define the function callback, arguments to pass, and the delay. Note that the function itself has the scope set to the chain instance and calls the next one in the chain. However, this can be modified as needed.
I hope this gives you some ideas.
Here's a second version using a decorator function to incorporate delays when calling the chain:
// Function decorator.
Function.implement({
chainDelay: function(delay, bind) {
// Allows setting a delay for chained functions and automatically calling the stack (if bind is a chain instance)
var self = this,
args = (arguments.length > 2) ? Array.slice(arguments, 2) : null;
return function() {
setTimeout(function() {
self.apply(bind, args.concat(Array.from(arguments)));
if (bind && bind.$chain && bind.$chain.length)
bind.callChain.call(bind);
}, delay);
}
},
justChain: function(bind) {
// Executes a chained function when due and auto-calls the stack for the next one (if bind is a chain instance and available)
var self = this, args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
return function() {
self.call(bind, args);
if (bind && bind.$chain && bind.$chain.length)
bind.callChain.call(bind);
}
}
});
var moo = new Chain();
moo.chain(
// Some delayed functions.
(function(what) {
console.log(what);
}).chainDelay(3000, moo, "hi"),
(function(what, ever) {
console.log(what, ever);
}).chainDelay(3000, moo, "there", "coda"),
(function(what) {
new Element("div[id=foo][html=" + what +"]").inject(document.body);
}).chainDelay(1000, moo, "mootools FTW!"),
// Regular functions included here as well.
(function() {
document.id("foo").setStyle("color", "red")
}).justChain(moo),
(function() {
document.id("foo").setStyle("background-color", "blue")
})
);
moo.callChain();
Example link: http://jsfiddle.net/dimitar/Y4KCB/4/