这是一个快速(破产)的jsfiddle:http://jsfiddle.net/wH2qF/
由于某种原因这不起作用......是因为我在另一个setTimeout中有一个setTimeout吗?
$(function() {
$("#Volume").click(function() {
setTimeout(triggerVolumeChange, 4000);
function triggerVolumeChange()
{
var volumeDiv = document.getElementById("volumeNumber");
var volumeOld = 8;
var volumeNew = 37;
var timeNew = (1000/(volumeNew-volumeOld));
changeVolume();
function changeVolume()
{
volumeDiv.innerHTML = volumeOld;
volumeOld++;
if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
};
});
});
为了清楚起见,我应该指明我从Click函数中删除了其他东西,并且澄清了什么不能正常工作,好吧,基本上,我点击并没有任何反应,而如果我删除了这一块代码它的工作原理很好...实际上变量的设置也可以正常工作(我自然是假设的)但是当我粘贴或取消注释changeVolume()函数时,点击会再次停止工作...有什么想法吗?
-
另一个澄清:我想要做的是,点击时,在一个字符串中模拟从值8到37的音量..因此该函数内的setTimeout。
-
根据你的家伙的要求,这是整个代码......我怀疑它是否有意义,但这里是......仅供参考,点击这将触发大量动画以模拟应用程序的流程我'设计..
<script>
$(function() {
$("#Volume").click(function() {
var userPrompt = document.getElementById("userPrompt")
userPrompt.innerHTML = "Change volume to 37";
var avatarIcon = document.getElementById("avatarIcon");
avatarIcon.innerHTML = "<img src='imgs/haloIcons-volume_82x76.png' alt='Volume'/>";
var hints = document.getElementById("hints");
hints.style.opacity = 0;
$(".dragonTvOut").toggleClass("dragonTvIn");
setTimeout(triggerP, 1000);
function triggerP()
{
var halo = document.getElementById('avatar');
if( 'process' in halo ) {
halo.process();
};
};
setTimeout(triggerUserPrompt, 2000);
function triggerUserPrompt()
{
document.getElementById("userPrompt").className = "userPromptIn";
};
setTimeout(triggerVolumeChange, 4000);
function triggerVolumeChange()
{
document.getElementById("userPrompt").className = "userPromptEnd";
var halo = document.getElementById('avatar');
if( 'resume' in halo ) {
halo.resume();
}
document.getElementById("avatarIcon").className = "avatarIconEnd";
var volumeDiv = document.getElementById("volumeNumber");
var volumeOld = 8;
var volumeNew = 37;
var timeNew = (1000/(volumeNew-volumeOld));
changeVolume();
function changeVolume()
{
volumeDiv.innerHTML = volumeOld;
volumeOld++;
if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
};
var side = 100;
var paper = new Raphael(volumeArcAnim, 100, 300);
paper.customAttributes.arc = function (xloc, yloc, value, total, R) {
var alpha = 360 / total * value,
a = (90 - alpha) * Math.PI / 180,
x = xloc + R * Math.cos(a),
y = yloc - R * Math.sin(a),
path;
if (total == value) {
path = [
["M", xloc, yloc - R],
["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
];
} else {
path = [
["M", xloc, yloc - R],
["A", R, R, 0, +(alpha > 180), 1, x, y]
];
}
return {
path: path
};
};
var arcWidth = 87;
var strokeRadius = arcWidth/2;
var indicatorArc = paper.path().attr({
"stroke": "#ffffff",
"stroke-width": 3,
arc: [side/2, side/2, 12, 100, strokeRadius]
});
indicatorArc.animate({
arc: [side/2, side/2, 60, 100, strokeRadius]
}, 1500, "<>", function(){
// anim complete here
});
};
});
});
</script>
答案 0 :(得分:3)
在您的破碎示例中http://jsfiddle.net/wH2qF/存在一些问题
ph
,但应为volumeNumber
(如HTML中所示)Click here to see a working version
如果您从jsfiddle中的库中选择了jQuery,您会看到错误
未捕获的TypeError:无法设置null
的属性'innerHTML'
这让我相信你的jsfiddle不能很好地代表你的问题。也许尝试创建另一个减少,因为你添加的只有“愚蠢”的错误?
答案 1 :(得分:2)
您错过了}
:
$(function() {
$("#Volume").click(function() {
setTimeout(triggerVolumeChange, 4000);
function triggerVolumeChange()
{
var volumeDiv = document.getElementById("volumeNumber");
var volumeOld = 8;
var volumeNew = 37;
var timeNew = (1000/(volumeNew-volumeOld));
changeVolume();
function changeVolume()
{
volumeDiv.innerHTML = volumeOld;
volumeOld++;
if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
};
} // that one was missing
});
});
答案 2 :(得分:1)
是的,您可以在另一个内部使用setTimeout()
- 这是用于重复定时事件的典型机制。
你的工作不起作用的原因与setTimeout()
本身无关;这与你嵌套函数的方式有关。
changeVolume()
内的triggerVolumeChange()
函数意味着您无法使用其名称直接引用它。
最快的解决方案是删除嵌套,以便changeVolume()
位于根级别而不是嵌套在triggerVolumeChange()
内。
答案 3 :(得分:0)
如果您不想使用setInterval()
,可以使代码适用于这些更改:
$(function() {
$("#Volume").click(function() {
setTimeout(triggerVolumeChange, 4000);
function triggerVolumeChange () {
var volumeDiv = document.getElementById("volumeNumber");
var volumeOld = 8;
var volumeNew = 37;
var timeNew = (1000/(volumeNew-volumeOld));
var changeVolume = function () {
volumeDiv.innerHTML = volumeOld;
volumeOld++;
if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
};
changeVolume();
}
});
});
jsFiddle的工作演示。
答案 4 :(得分:0)
从技术上讲,计时器从何处开始没有区别。在大多数情况下,它是作为带有标识符和关联的回调处理程序的计时器列表实现的。
因此,如果您的逻辑正确,那就可以了。没有带来无限调用序列的不可预测条件,也没有无限数量的超时实例,等等。
例如模仿setInterval
函数:
// Bad (unexpected multiple sequences started per each event)
const handler = () => {
setTimeout(handler)
}
<Button onClick={handler} />
// Good (previous interval closed before start new one)
const [id, idUpdate] = useState(-1)
const handler = () => {
const id = setTimeout(handler)
idUpdate(id)
}
const start = () => {
if(id !===-1) clearTimeout(id)
idUpdate(-1)
handler()
}
<Button onClick={start} />
或其他
// Bad (infinite events with small time will take all cpu time)
const handler = () => {
setTimeout(handler, 0) // actually mean several ms
}
// Good (special condition for finish iterations)
let count = 20
const handler = () => {
if(!count) return
count--
setTimeout(handler, 0)
}