Interval(或timeOut)内的jquery.animate在清除后继续
jquery .animate within Interval (or timeOut) keeps going after clear
我正在学习JS,使用一些代码将音频(口语)与文本(口语的转录)大致同步。
更具体地说,代码逐个字符地改变文本的背景颜色,相当于播放音频的ms。此外,您可以单击文本中的任何字符以转到音频中的等效ms。
我使用Bart-Veneman扳手自动为文本中的每个字符添加跨度,然后Jquery使用for循环和这些跨度来设置这些字符的背景颜色的动画。背景颜色。每个角色的动画需要+-240ms。
由于音频持续更新似乎不太可靠,我使用了一个间隔作为计时器:它在音频开始时开始,并与之平行运行。背景颜色。动画发生在这个间隔内。
?怎么了:如果你访问网站(在Firefox下工作,而不是Chrome)并点击文本的任何部分(音频开始播放),然后点击文本的其他部分(音频播放点改变),你会注意到一些文本字符的背景色仍然存在。这些字符的背景颜色未正确清除:
?我的猜测是什么:发生这种情况是因为背景色+-240ms。动画发生的时间与我调用clearInterval的时间与清除背景色的for循环发生的时间之间的关系。
更多信息:清除背景颜色和间隔的for循环都在audio.onplay.时触发的函数中运行
当单击文本字符时,音频将暂停,播放点将更改,audio.onplay将启动,因此调用该函数。
clearInterval在Interval本身内,如果audio.onpause或on.end(以及到达文本的最后一个字符),则运行clearInterval。
我读过Intervals循环,而没有等待其中的代码块完成,所以我也尝试过在这里超时,得到了相同的结果。
?到底发生了什么??解决这个问题的好方法是什么?
谢谢
完整代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head>
<meta charset="UTF-8">
<title>masculinidades/masculinities TEST 5</title>
</head>
<body>
<audio id="miAudio" preload="auto" controls><source src=audio/talk.mp3 type="audio/mpeg"></audio>
<p id="text">La lógica del empresario criminal, el pensamiento de los
boss coincide con el neoliberalismo más radical. Estar en
situación de decidir sobre la vida y la muerte de todos</p>
<script src="js/spanner.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script>
$(document).ready(function(){
// spanner aplica span .char* en orden creciente al contenido del elemento #text
spanner( document.getElementById("text") );
// guardar el elemento audio y el tamaño del texto en variables
var elAudio = document.getElementById("miAudio");
var durText = $("#text").text().length;
// calcular cada cuantos ms hemos de de avanzar un caracter
var msXchar = Math.floor((elAudio.duration*1000) / durText);
console.log("1 Char cada " + msXchar + " ms");
// al hacer hover en cualquier elemento con clase char(int) colorea y pon cursor
$("[class^='char']").hover(
function() {
$(this).css('cursor', 'e-resize');
if ($(this).css("backgroundColor") != "rgb(0, 250, 154)") {
$(this).css("backgroundColor", "rgb(0, 250, 154)");
} else {
$(this).css("backgroundColor", "rgb(255, 255, 255)");
};
}, function() {
if ($(this).css("backgroundColor") == "rgb(0, 250, 154)") {
$(this).css("backgroundColor", "rgb(255, 255, 255)");
} else {
$(this).css("backgroundColor", "rgb(0, 250, 154)");
};
}
);
/* al hacer click en cualquier elemento con clase char(int) usa (int) para ir al tiempo del audio equivalente */
$("[class^='char']").click(
function() {
elAudio.pause();
console.log("clicked paused")
//extrae el int y escala a tiempo de audio
var thisChar = $(this).attr('class').substring(4);
var thisTime = ((thisChar / durText) * (elAudio.duration));
//muévete a ese tiempo de audio
elAudio.currentTime = thisTime + (msXchar*2/1000)
console.log(thisChar, thisTime);
elAudio.play();
}
);
// cuando se hace play al audio ...
elAudio.onplay = function() {
console.log("onplay");
// + borra todo caracter coloreado
for (var i = 0; i < (durText+1); i++) {
$(".char" + i).css("backgroundColor", "#ffffff")
};
// en qué MILIsegundo del audio estamos y a q equivale en texto?
var actualTime = Math.floor(elAudio.currentTime*1000);
var actualChar = Math.floor(((actualTime/1000) / elAudio.duration) * (durText));
console.log("start " + "ms: " + actualTime , "char: " + actualChar);
// ... inicia un Interval que avanza paralelamente al audio
var elInterval = setInterval(function(){
// colorea el actual char
console.log("start colorea")
$( ".char" + actualChar).animate({
backgroundColor: '#00fa9a'
}, (msXchar*4) );
console.log("end colorea")
// cada loop subir 1 el contador de caracteres, empezando en actualChar
actualChar += 1;
console.log("char actual " + actualChar);
// y subir en msXchar ms el contador de tiempo
actualTime += msXchar;
// si el num de char actual es mayor que el largo total del texto, detenemos el intervalo, lo mismo si se ha pausado o terminado el audio
if (actualChar > (durText)) {clearInterval(elInterval);
console.log("interval cleared actualChar > durText");};
elAudio.onpause = function(){clearInterval(elInterval);
console.log("interval cleared paused");};
elAudio.onended = function(){clearInterval(elInterval);
console.log("interval cleared ended");};
// repite este intervalcada msXchar ms
}, msXchar);
};
});
</script>
</body>
</html>
animate
方法将异步工作。不同步(每个
jQuery.fn.animate
都会创建用于设置动画的计时器。)
所以,您不仅需要清除定时器,还需要清除动画队列。
参见参考文献
.animate(...)
:https://api.jquery.com/animate/
.stop(...)
):https://api.jquery.com/stop/
.finish(...)
:https://api.jquery.com/finish/
Demo
http://codepen.io/mooyoul/pen/NxRJOr
- document.open/document.write没有正确地清除chrome中的文档——这是chrome的错误吗
- 单击jquery清除输入值
- 如何在Microsoft VirtualEarth 6.3中使用纯javascript清除整个形状层
- 清除以前的$_GET值或不获取仅隐藏字段的值
- 可以'使用jQuery animate时无法看到动画
- 如何使用jquery animate来回移动多个元素
- Javascript清除缓存以清除基本身份验证凭据
- jQuery animate()函数没有't设置动画
- JQuery.animate();不以固定高度工作
- $animate addClass在angular 1.3中不起作用
- 清除启动日期选取器值
- 在 SlickGrid 中编辑后,根据不同列中的另一个单元格清除单元格
- php页面,该页面在清除值后接受输入
- JS异常:animate不是一个函数
- 清除数据并将旧值附加到文本框中
- 关于使用Animate.css向和项添加和删除动画类的问题
- 使用javascript清除Asp.NET FreeTextBox(RTF文本框)
- 如何使Visual Studio自动清除Javascript控制台
- 使用javascript或html本身清除文本字段
- Interval(或timeOut)内的jquery.animate在清除后继续