我正在开发一个WordPress(Javascript)插件,它根据用户与HTML5滑块的交互来改变文本字段。其中一个效果是使用SetTimeout一次显示一个<span>
字符串一个字符来创建一个延迟(几毫秒),因此效果是可察觉的。我通过获取DOM元素的内容然后一次重建一个字符来实现这一点。
问题在于,由于SetTimeout是非同步的,因此用户可以比单个揭密循环完成更快地移动滑块,从而导致半空DOM元素永远不会得到纠正。
有没有办法防止这种情况,或者是一种完成避免冲突的任务的方法?我已尝试在延迟循环中的各个点关闭EventListener(对于HMTL5),但找不到避免问题的地方。另一种可能性是将所有 <span>
内容加载到数组中,以保留所有内容的完整副本......但有些东西告诉我有更好的方法来做到这一点我不做知道。
这是示例代码。当涉及的HTML页面加载时,将调用Initialize()。
function Initialize () {
document.getElementById(name).addEventListener('input', UpdateSlider);
}
function UpdateSlider()
{ if (
// conditions
)
{ var cols = document.getElementsByClassName(attr+i);
RevealTextLines (cols);
}
// 'delay' is a global variable to set the delay length
function RevealTextLines (cols)
{
[].forEach.call(cols, function(el) {
var snippet = el.innerHTML;
el.innerHTML = '';
el.style.display = 'inline';
(function addNextCharacter(h) {
el.innerHTML = snippet.substr(0,h);
h = h + numchars;
if (h <= snippet.length) {
setTimeout(function() {
addNextCharacter(h);
}, delay);
}
})(1);
});
}
答案 0 :(得分:1)
上面建议的布尔标志在这种情况下不起作用,但确实激发了以下解决方案:
如果预先知道迭代次数(在这种情况下它们是),则在函数外部定义一个全局计数器变量。在SetTimeout循环之前,将其设置为迭代次数并每次减少1。然后只有在计数器的值为零时才能进行调用功能。
const shell = require('electron').shell;
// assuming $ is jQuery
$(document).on('click', 'a[href^="http"]', function(event) {
event.preventDefault();
shell.openExternal(this.href);
});
如果有人知道更有效的解决方案,我会保持兴趣。