BOLD denotes updates.
I have an array, steps, whose contents are objects with an action and element associated with them. Like so:
steps = [{action: 'click', element: <jQuery element>},
{action: 'click', element: <jQuery element>}, ., ., N]
I would like to implement a runner, whose job is to run through each element in the array and perform the particular action upon the element. Each step must be performed in serial. So for example, if you have:
steps = [{action: 'click', element: <jQuery element representing a button>},
{action: 'click', element: <jQuery element representing an anchor tag>}]
Running, run(steps, timeout), would run through each step. step[0].action would be performed on step[0].element. Since it is possible for step[0] to create the dom element (by means of AJAX) to be interacted with in step[1], the runner needs to wait a particular period(hence, the timeout), polling the dom for the presence of step[1].element.
Here is a rough take at what I have so far:
var run = function() {
$.each(steps, function(i, v) {
var interval = 25,
start = 0,
timeout = 3000;
var i = setInterval(function(timeout) {
start = start + interval;
console.log(start);
if ($(v).is(':visible')) {
v.click();
console.log('clicked', v);
clearInterval(i);
}
}, interval);
});
};
Note that in the above example, steps is just an array of jquery objects. It isn’t in the desired format just yet:
steps = [{action: 'click', element: <jQuery element>},
{action: 'click', element: <jQuery element>}, ., ., N]
What is the ‘pattern’ so to say, that I need to follow? Do I need to use deferred objects to take care of this? Is it implemented with a setTimeout, setInterval? Thanks!
Final implementation
var run = function(steps, interval, timeout) {
var timer,
time = 0,
i = 0;
runSingle(steps[0]);
function abort() {
console.log("Run aborted");
}
function runSingle(step) {
timer = setInterval(function() {
time += interval;
if ($(step.element).is(':visible') === true) {
clearInterval(timer);
time = 0;
$(step.element).trigger(step.action);
(i < (steps.length - 1)) && runSingle(steps[++i]);
} else if (time >= timeout) {
clearInterval(timer);
abort();
}
}, interval);
console.log("Performed: ", step.action, "on", step.element)
if (i === (steps.length - 1)) console.log("Run successful");
}
}
Here’s something. I haven’t tested it thoroughly:
See it here in action: http://jsfiddle.net/myaeh/