我会使用按构建的解决方案。一定有一款适合您的需求。像jTour这样简单的东西,或者如果不包括它,像Scriptio这样更复杂的东西。您可能也对这个问题的一些答案感兴趣。
编辑
如果您不想使用预先存在的解决方案,我会这样做:
var runTutorial = (function () {
// The command object holds all the different commands that can
// be used by someone for the tutorial. Each of these commands
// will recive a callback set as their `this`. This
// callback should be called by your commands when they are done
// running. The person making the tutorial won't need to know
// about the callback, the code will handle that.
var commands = {
wrap: function () {
//wrap the page in an iframe
this();
},
playsound: function (soundPath, soundLength) {
//playing a sound (duh)
setTimeout(this, soundLength);
},
highlight: function (selector) {
//animation that highlights an element.
//I'm using jQuery UI for the animation here,
// but most animation libraries should provide
// a callback for when the animation is done similarly
$(selector).effect('highlight', 'slow', this);
},
loadpage: function (pageUrl) {
//loading a new page
setTimeout(this, 500);
},
waitForClick: function () {
// when we go into the click handler `this` will no
// longer be availble to us since we will be in a
// different context, save `this` into `that` so
// we can call it later.
var that = this;
$(document).one('click', function () {
that();
});
}
},
// This function takes an array of commands
// and runs them in sequence. Each item in the
// array should be an array with the command name
// as the first item and any arguments it should be
// called with following as the rest of the items.
runTutorial = function (commandList) {
var nextCommand = function () {
if (commandList.length > 0) {
var args = commandList.shift();
// remove the command name
// from the argument list
cmd = args.shift(1);
// call the command, setting nextCommand as `this`
commands[cmd].apply(nextCommand, args);
}
}
nextCommand();
};
return runTutorial;
}());
$('#tutorialbutton').click(function() {
runTutorial([
['playsound', 'media/welcome', 1000],
['highlight', '[name=firstname]'],
['playsound', 'media/welcome2', 1500],
['waitForClick'],
['loadpage', page2],
['playsound', 'media/page2', 100]
]);
});
该runTutorial
函数采用一个简单的数组,其中包含按应运行顺序排列的命令及其参数。无需用回调来打扰编写脚本的人runTutorial
,为他们处理。与需要编写器管理回调的系统相比,这具有一些很大的优势。您不需要像使用显式回调那样为脚本中的每一行指定一个唯一的名称,也不需要无休止地嵌套匿名函数。您无需重新连接任何东西来更改命令的播放顺序,您只需在阵列中重新排列它们即可。
你可以玩的jsfiddle
您的每个命令都需要等待其操作完成,然后才能调用其回调(又名this
)。我在小提琴中使用setTimeout
. 例如,如果您使用 jQuery 的.animate
for highlight
,它提供了一个complete
在动画完成时触发的处理程序,只需坚持this
(不带调用括号()
)在那里。如果您使用的是 jQuery UI,它具有内置的“高亮” 效果,因此您可以像这样实现它:
highlight: function (selector) {
//animation that highlights an element.
$(selector).effect('highlight', 'slow', this);
},
大多数其他提供动画的库应该提供类似的回调选项,您可以使用。
根据您播放它们的方式,控制声音的回调可能会更难。如果您使用的方法没有提供回调或轮询它的方式以查看它是否已完成,您可能只需要添加另一个参数,playsound
该参数以毫秒为单位获取声音的长度,然后在继续之前等待那么长时间:
playsound: function (soundPath, soundLength) {
//playing a sound (duh)
setTimeout(this, soundLength);
},