2016-05-25 118 views
1

之前,我组建了一个PowerPoint演示类型的网页,在幻灯片中的观点与各种动画和滑动。动画序列保存在一个数组中(最终从数据库中加载),并使用eval()调用JavaScript的等待动画完成一个动画

当单击幻灯片时,下一组动画被执行,但我需要每一个动画都要等到先前一个已经完成。所以对于下面的代码,当SeqNo是1时,我希望ShowSlideLeft等到HideSlideRight完成。

我已经看过回调和承诺,但我不能让他们的工作,因为我不能硬编码的链接事件。

var SeqNo; 

$(document).ready(function() { 
    $('.slide').click(function (e) { 
     ActivateSequence(++SeqNo); 
    }); 

    SeqNo = 0; 

    SetupSequence(); 

    ActivateSequence(SeqNo); 
}); 

function SetupSequence() { 
    Sequence = []; 

    Sequence[0] = []; 
    Sequence[0][0] = "ShowSlideLeft('S1');"; 

    Sequence[1] = []; 
    Sequence[1][0] = "HideSlideRight('S1');"; 
    Sequence[1][1] = "ShowSlideLeft('S2');"; 
} 

function ActivateSequence(Seq) { 
    var action; 
    var element; 

    if (Seq < Sequence.length) { 
     for (var i = 0; i < Sequence[Seq].length; i++) { 
      eval(Sequence[Seq][i]); 
     } 
    } 
} 

function ShowSlideLeft(div) { 
    var showoptions = { "direction": "left", "mode": "show" }; 
    $('#' + div).effect("slide", showoptions, 1000); 
} 

function ShowSlideRight(div) { 
    var showoptions = { "direction": "right", "mode": "show" }; 
    $('#' + div).effect("slide", showoptions, 1000); 
} 

function HideSlideLeft(div) { 
    var showoptions = { "direction": "left", "mode": "hide" }; 
    $('#' + div).effect("slide", showoptions, 1000); 
} 

function HideSlideRight(div) { 
    var showoptions = { "direction": "right", "mode": "hide" }; 
    $('#' + div).effect("slide", showoptions, 1000); 
} 

非常感谢您的任何帮助。

+0

嗯,你知道,每个动画将持续1000毫秒,为什么不把每个动画等待1000毫秒之前它允许开始(如果另一个先前已经开始,没有结束)? –

回答

1

您可以通过.effect()第四个参数的回调,这是一个在动画完成后调用的函数。 所以,你可以通过添加一个回调参数传递下来的.effect呼叫,像这样的改变您的自定义功能:

function ShowSlideLeft(div, callback) { 
    var showoptions = { "direction": "left", "mode": "show" }; 
    $('#' + div).effect("slide", showoptions, 1000, callback); 
} 

您还需要改变SetupSequenceActivateSequence,我建议你:

  • window[function_name]替换eval实现实际的函数调用
  • 初始化Sequence阵列对象,而不是字符串(它们可以被存储在数据库如JSON字符串,所以这种变化不应该在数据库设计的影响)

其结果将是这样的:

function SetupSequence() { 
    Sequence = []; 

    Sequence[0] = []; 
    Sequence[0][0] = { action: 'ShowSlideLeft', target: 'S1' }; 

    Sequence[1] = []; 
    Sequence[1][0] = { action: 'HideSlideRight', target: 'S1' }; 
    Sequence[1][1] = { action: 'ShowSlideLeft', target: 'S2' }; 
} 

function ActivateSequence(Seq, Step) { 
    if (Seq < Sequence.length) { 
     (window[Sequence[Seq][Step].action])(Sequence[Seq][Step].target, function() { 
      // when the first effect is complete, execute the next one 
      ActivateSequence(Seq, Step + 1); 
     }); 
    } 
} 

请注意,有轻微您还可以将自定义效果功能的一组参数传递给参数target而不是像现在这样。

当然,您需要在click处理程序中调用ActivateSequence(SeqNo, 0)的ActivateSequence。

+0

这看起来非常感谢。不知道为什么目前,但回调不是触发,所以第二个动画没有执行。我将在稍后调查,因为我必须弹出。再次感谢。 – pbs

+1

非常感谢。我犯了一个错字,只需要在回调中添加一个支票,以确保在调用之前还有另一个步骤可以执行。我今天学到了东西 - 谢谢。 – pbs

0

我看到你已经在使用jQuery,为什么不使用自己的动画API?

$('.some-element').animate({width:200}, 400, callback); 

您提供了一个更改对象,它应该执行的时间和一个回调函数。