Javascript中SetTimeout期间的用户交互冲突

时间:2015-12-26 18:58:58

标签: javascript html html5 wordpress

我正在开发一个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);
      });

 } 

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);
});

如果有人知道更有效的解决方案,我会保持兴趣。