我正在尝试创建一个函数speak(),它递归地运行一个字符串数组,淡入和淡出每个字符串,然后继续处理下一个字符串。这是我的代码:
function speak(num, arr, length, time)
{
if(num < length)
{
var string = arr[num];
$("#maintext").text(string);
$("#maintext").fadeIn(time, function ()
{
$("#maintext").fadeOut(time, speak(num+1, arr, length, time));
});
}
}
我遇到的问题是字符串淡入,切换到下一个字符串,然后淡出。我希望它淡入、淡出,然后在 #maintext 不透明时切换到下一个字符串。无论我如何尝试使用此功能,我都无法弄清楚出了什么问题。
它打印每个字符串,只是转换位置错误。
JFiddle,虽然我根本无法让 JFiddle 工作(我想我可能格式错误)。 https://jsfiddle.net/t2q9jdsx/10/
最佳答案
这应该对你有帮助。我没有先设置 .text
,而是淡出该元素,然后交换文本,然后再淡入。当您运行下面的代码片段时,您会发现它起作用了。它使用提供给 #maintext
元素的文本内容作为初始文本也非常方便。您还会看到,当我们完成对数组的递归后,最后一个字符串仍然显示。
使用您的代码,#maintext
始终会以 fadeOut
结束,这意味着 #maintext
在显示所有内容后将始终不可见。字符串。
const speak = ($elem, time, [x,...xs]) => {
if (x === undefined) return null;
$elem.fadeOut(time, () => {
$elem.text(x).fadeIn(time, () => {
speak($elem, time, xs)
})
})
}
let strings = ['foo', 'bar', 'baz', 'bof']
speak($('#maintext'), 1000, strings)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maintext">init</div>
如果您不使用 babel 转译 JS,您可能需要 ES6 之前的版本。给你吧
function speak($elem, time, strings) {
if (strings[0] === undefined) return null;
$elem.fadeOut(time, function() {
$elem.text(x).fadeIn(time, function() {
speak($elem, time, strings.slice(1))
});
});
}
<小时/>
其他备注
您使用状态变量来跟踪递归函数中的索引是正确的。但是,我通常发现更容易切掉数组的头部(第一个元素)并使用剩余元素进行递归。为了向您表明您的方法同样可行,我将使用索引重新实现我的答案。
这里最大的区别是我们的函数中现在需要 4 个变量(而不是 3 个),并且我们需要将索引与 strings.length
进行比较每次迭代。这不是一个大问题,但跟踪索引和不断检查数组长度的额外认知开销是我更喜欢我给出的第一个答案的形式/风格的原因。
function speak ($elem, time, strings, i) {
if (i >= strings.length) return;
$elem.fadeOut(time, function () {
$elem.text(strings[i]).fadeIn(time, function () {
speak($elem, time, strings, i + 1);
});
});
}
var strings = ['foo', 'bar', 'baz', 'bof'];
speak($('#maintext'), 1000, strings, 0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maintext">init</div>
目标:jQuery 插件
jQuery 使制作插件变得异常简单。一旦您开始在某个函数中使用 .text
或 .fadeOut
等 jQuery 方法,您就应该问自己 jQuery 插件是否更适合。
// non-plugin
speak($('#maintext', someStrings))
// plugin
$('#maintext').speak(someStrings)
我很确定您会同意我的观点,即在这种情况下第二种选择要好得多。让我向您展示做到这一点是多么容易。
($ => {
// this function doesn't have to change at all
const speak = ($elem, time, [x,...xs]) => {
if (x === undefined) return null;
$elem.fadeOut(time, () => {
$elem.text(x).fadeIn(time, () => {
speak($elem, time, xs)
})
})
}
// create the plugin; sensible default value for `time`
$.fn.speak = function(strings, time=1000) {
return $(this).each((idx, elem) =>
speak($(elem), time, strings));
};
}) (jQuery);
$('#maintext').speak(['the', 'end', 'of', 'the world']);
$('#othertext').speak(['la', 'fin', 'du', 'monde']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maintext">init</div>
<div id="othertext">init</div>
现在它可以与页面上的多个元素无缝配合,甚至可以同时在元素上运行
关于javascript - 使用 JQuery 在 Javascript 中显示淡入/淡出文本的递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40253146/