为什么setTimeout不能在这个函数中工作?

时间:2014-10-22 21:12:51

标签: javascript tabs toggle settimeout addeventlistener

我创建了一个生成标签的功能。它的工作原理是将元素ID作为参数,然后生成一个事件监听器,然后响应任何元素的单击事件。它有点复杂,所以我发布它:

function toggleTabs() {
  var panel = [], li = [];
  for(var i = 1, j = arguments.length; i <= j; i++) {
    li[i] = document.getElementById(arguments[i - 1]);
    panel[i] = 'panel' + i;
  }  
  document.getElementById('toggle').addEventListener('mouseup', function(event) {
    var target = event.target.id;
    for(var i = 1, j = li.length; i <= j; i++) {
      if(li[i].id === target) {
        document.getElementById(panel[i]).style.display = 'block';
        setTimeout(function() {
          document.getElementById(panel[i]).style.opacity = '1';
          window.alert('fired');
        }, 500);
        li[i].className = 'active';
      } else if(target.substring(0,3) === 'tab'){
        document.getElementById(panel[i]).style.display = 'none';
        document.getElementById(panel[i]).style.opacity = '0';
        li[i].className = null;
      }
    }
  }, false);
}
if(url === '/customers') { toggleTabs('tab-c-featured', 'tab-c-view'); }

实际上,它有效,但我希望元素在触发时淡入,尽管元素上存在转换效果,但这种情况并未发生。我认为这可能是因为显示属性也改变了,覆盖了淡入不透明效果,所以我决定添加一个超时效果 - 但它不起作用。我添加了一个窗口警报来测试它,由于某种原因它不会开火,为什么会这样?

感谢

1 个答案:

答案 0 :(得分:1)

可能有错误。在循环内创建延迟函数调用时,必须使用闭包。 所以这是错误document.getElementById(panel[i]).style.opacity = '1';

当调用该函数时,panel[i]将引用panels列表的最后一个元素。 为了避免这种行为,请将您的调用包装起来,例如
setTimeout(function (thePanel) { return function(){ // do whatever you need with thePanel } }(panel[i]), 500);

There is more info about this problem at SO