gpt4 book ai didi

javascript - 间隔(或超时)内的jquery .animate在清除后继续进行

转载 作者:行者123 更新时间:2023-12-03 01:57:03 25 4
gpt4 key购买 nike

我正在学习 JS,使用一些代码将音频(口语)与文本(口语的转录)大致同步。

更具体地说,该代码逐个字符地更改文本的背景颜色,相当于播放音频的毫秒数。此外,您可以单击文本的任何字符以转到音频中的等效 ms。

我正在使用 Bart Veneman Spanner 自动将跨度添加到我的文本中的每个字符,然后使用 Jquery 使用 for 循环和这些跨度为这些字符的背景颜色设置动画。背景颜色 .animation 每个字符需要 +-240 毫秒才能发生。

由于音频 ontimeupdate 似乎不太可靠,我使用间隔作为我的计时器:它在音频开始时开始并与之并行运行。背景颜色 .animation 在此间隔内发生。

有什么问题? : 如果你 visit the website (在 Firefox 下工作,而不是 Chrome)并单击文本的任何部分(音频开始播放),然后单击文本的其他部分(音频播放点更改),您会注意到一些文本字符的背景颜色仍然存在。这些字符的背景颜色未正确清除:

¿ 我的猜测是什么? :这是因为背景颜色 .animation 发生 +-240ms VS 如何/何时我调用 clearInterval VS 如何/何时发生清除背景颜色的 for 循环。

更多信息 :
清除背景颜色和间隔的 for 循环都在 audio.onplay 时触发的函数中运行。

单击文本字符时,会暂停音频,更改播放点,并触发 audio.onplay,因此调用该函数。

clearInterval 在 Interval 本身内,并且在 audio.onpause 或 on.ended (以及如果到达文本的最后一个字符)时运行。

我已经阅读了 Intervals 循环,而没有等待其中的代码块完成,所以我也尝试了超时 here ,结果相同。

¿ 究竟发生了什么?
¿ 有什么好的方法可以解决这个问题?

谢谢

完整代码:

    <!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/

演示

http://codepen.io/mooyoul/pen/NxRJOr

关于javascript - 间隔(或超时)内的jquery .animate在清除后继续进行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34484308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com