Javascript 实现一个遍历数组的运行程序
粗体表示更新 我有一个数组,Javascript 实现一个遍历数组的运行程序,javascript,jquery,asynchronous,Javascript,Jquery,Asynchronous,粗体表示更新 我有一个数组,steps,它的内容是带有动作和元素的对象。像这样: steps = [{action: 'click', element: <jQuery element>}, {action: 'click', element: <jQuery element>}, ., ., N] 注意,在上面的示例中,steps只是jquery对象的数组。它还没有达到所需的格式: steps = [{action: 'click', elemen
steps
,它的内容是带有动作和元素的对象。像这样:
steps = [{action: 'click', element: <jQuery element>},
{action: 'click', element: <jQuery element>}, ., ., N]
注意,在上面的示例中,steps
只是jquery对象的数组。它还没有达到所需的格式:
steps = [{action: 'click', element: <jQuery element>},
{action: 'click', element: <jQuery element>}, ., ., N]
steps=[{action:'click',element:},
{操作:'click',元素:},,,N]
我需要遵循的“模式”是什么?我需要使用延迟对象来处理这个问题吗?它是用setTimeout、setInterval实现的吗?谢谢
最终实施
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");
}
}
var run=function(步骤、间隔、超时){
var定时器,
时间=0,
i=0;
runSingle(步骤[0]);
函数中止(){
日志(“运行中止”);
}
函数runSingle(步骤){
计时器=设置间隔(函数(){
时间+=间隔;
if($(step.element).is(':visible')==true){
清除间隔(计时器);
时间=0;
$(step.element).trigger(step.action);
(i<(步骤长度-1))&运行单个步骤[++i];
}否则如果(时间>=超时){
清除间隔(计时器);
中止();
}
},间隔);
日志(“已执行:”,step.action,“on”,step.element)
if(i==(steps.length-1))console.log(“运行成功”);
}
}
首先,请注意,在您的示例中,v
变量将表示数组中的一个对象,因此说v.click()
或$(v).is(':visible')
-您应该说v.element.click()
或v.element.is(':visible')
如果您的意思是action
将是一个字符串,它是jQuery方法的名称,element
是一个jQuery对象,那么您可以这样做:
$.each(steps, function(i, obj) {
obj.element[obj.action]();
});
var run = function(steps, delay, timeout) {
var i = 0,
nextStep = function() {
if (i < steps.length) {
var step = steps[i],
retryDelay = 25,
retryTotal = 0,
intervalId = setInterval(function() {
retryTotal += retryDelay;
var $el = $(step.element);
if ($el.is(':visible')) {
$el[step.action]();
clearInterval(intervalId);
i++;
setTimeout(nextStep, delay);
} else if (retryTotal >= timeout) {
clearInterval(intervalId);
}
}, retryDelay);
};
}
nextStep();
};
run(steps, 50, 3000);
如果element
是一个字符串,表示应用于创建jQuery对象的选择器,则:
$.each(steps, function(i, obj) {
$(obj.element)[obj.action]();
});
您不需要引入轮询概念,除非操作
可能会异步执行某些操作,例如,如果它进行淡入,或者通过Ajax添加元素
在您的示例中,对于是否继续当前步骤,您似乎应用的唯一标准是当前元素是否可见。如果是这种情况,您可以这样做:
$.each(steps, function(i, obj) {
obj.element[obj.action]();
});
var run = function(steps, delay, timeout) {
var i = 0,
nextStep = function() {
if (i < steps.length) {
var step = steps[i],
retryDelay = 25,
retryTotal = 0,
intervalId = setInterval(function() {
retryTotal += retryDelay;
var $el = $(step.element);
if ($el.is(':visible')) {
$el[step.action]();
clearInterval(intervalId);
i++;
setTimeout(nextStep, delay);
} else if (retryTotal >= timeout) {
clearInterval(intervalId);
}
}, retryDelay);
};
}
nextStep();
};
run(steps, 50, 3000);
var run=函数(步骤、延迟、超时){
var i=0,
下一步=函数(){
如果(i<步长长度){
var步骤=步骤[i],
retryDelay=25,
retryTotal=0,
intervalId=setInterval(函数(){
retryTotal+=retryDelay;
var$el=$(步骤元素);
如果($el.is(':visible'){
$el[步骤行动]();
clearInterval(intervalId);
i++;
设置超时(下一步,延迟);
}否则如果(retryTotal>=超时){
clearInterval(intervalId);
}
},retryDelay);
};
}
下一步();
};
运行(步骤503000);
run()
函数定义了一个nextStep()
函数,该函数使用setInterval
不断检查当前元素是否可见。一旦完成,它将执行该操作,清除间隔,并通过setTimeout
调用自身来移动到下一个元素
我不确定如何将超时概念与轮询结合起来,因为如果当前元素在指定的时间后不可见,您会怎么做?您不能真正继续下一个元素,因为它也可能依赖于前面的步骤。我想您可以通过清除间隔而不再调用
nextStep()
来中止整个过程编辑:我已经更新了代码,以便按照最后一句话工作。这里有一些东西。我没有彻底测试它:
var run = function(steps, interval)
{
var timer,
time = 0, timeout = 10000,
ciel = steps.length - 1,
i = 0;
run_single(steps[0]);
function run_single(item)
{
timer = setInterval(function()
{
var $el = $(item.selector);
time += interval;
if ( $el.length )
{
clearInterval( timer );
time = 0;
$el.trigger( item.action );
i < ciel && run_single( step[ ++i ] );
}
else
{
if ( time >= timeout ) clearInterval( timer );
}
}, interval);
}
};
var steps = [
{action: 'click', selector: '#first'},
{action: 'hover', selector: '#second'},
{action: 'change', selector: '#third'}
// and so on...
];
run(steps, 100);
var run=函数(步骤、间隔)
{
var定时器,
时间=0,超时=10000,
ciel=步长。长度-1,
i=0;
单次运行(步骤[0]);
单个功能运行(项目)
{
计时器=设置间隔(函数()
{
var$el=$(item.selector);
时间+=间隔;
如果($el.length)
{
清除间隔(计时器);
时间=0;
$el.触发器(项目.操作);
i=超时)清除间隔(计时器);
}
},间隔);
}
};
变量步骤=[
{操作:'click',选择器:'#first'},
{操作:'hover',选择器:'#second'},
{操作:'change',选择器:'#third'}
//等等。。。
];
运行(步骤100);
请参见此处的操作:是
表示jQuery对象,还是仅表示用作jQuery选择器的CSS选择器?如果它已经是jQuery对象,那么在向DOM添加新元素时它不会更新……谢谢。当前它是一个jqueryobject,我必须更新它才能使用选择器。如果您的选择器是一个类选择器,并且页面上已经有其他元素与该类一起使用,您如何知道前面的函数是否已经完成了它的工作?抱歉。我应该更清楚地说明,单击任何元素都可以通过ajax创建dom元素。我将更新这篇文章。另外,为了澄清这个问题,“如果当前元素在指定的时间之后不可见,那么