如果为true则设置超时,在其他时取消它

时间:2015-11-04 10:37:01

标签: javascript jquery settimeout

所以,我在鼠标悬停/鼠标移出事件上调用此函数。首先(鼠标悬停)我用'open'参数调用它,然后用鼠标输出'close'参数。

我想在叠加显示中添加延迟,并在超时到期之前使用'close'取消显示该功能。

如果没有超时,函数会在鼠标输出时立即进入'close'分支,超时事件在超时结束时不会运行if,这样window.clearTimeout(emgOverTimer);就无法完成其魔法。< / p>

function emgFluidOverlayShow(action, currentElement) {
    var $overlay = $('#emg-fluid-overlay');

    if (action == 'open') {
        var emgOverTimer = setTimeout(function() {
            $(currentElement).addClass('emg-fluid-bring-front');
            $overlay.addClass('emg-fluid-anim-overlay');
            $overlay.data('statuson', true);
        }, 1000);
    } 
    else if (action == 'close') {
        window.clearTimeout(emgOverTimer);
        console.log(1);
        $overlay.removeClass('emg-fluid-anim-overlay');
        $overlay.data('statuson', false);
        $('.emg-fluid-header').find('.emg-fluid-bring-front').removeClass('emg-fluid-bring-front');
    }
}

1 个答案:

答案 0 :(得分:2)

您的emgOverTimer变量是函数中的 local 变量,因此在后续调用函数时,它与不同的变量不同于之前的电话。

将其移至包含范围,以便所有emgFluidOverlayShow函数调用使用相同的变量:

var emgOverTimer = 0;                                  // <=== Declaration
function emgFluidOverlayShow(action, currentElement) {
  var $overlay = $('#emg-fluid-overlay');

  if (action == 'open') {
   emgOverTimer = setTimeout(function() {              // <=== No `var` here
    $(currentElement).addClass('emg-fluid-bring-front');
    $overlay.addClass('emg-fluid-anim-overlay');
    $overlay.data('statuson', true);
   }, 1000);

  } else if (action == 'close') {
    window.clearTimeout(emgOverTimer);
    console.log(1);
    $overlay.removeClass('emg-fluid-anim-overlay');
    $overlay.data('statuson', false);
    $('.emg-fluid-header').find('.emg-fluid-bring-front').removeClass('emg-fluid-bring-front');
  }
}

我还会更新逻辑以处理多个open调用的情况,方法是在if (action == 'open')之后插入:

window.clearTimeout(imgOverTimer);

并清除定时器回调中的定时器句柄以及close案例:

imgOverTimer = 0;

所有在一起:

var emgOverTimer = 0;
function emgFluidOverlayShow(action, currentElement) {
  var $overlay = $('#emg-fluid-overlay');

  if (action == 'open') {
   window.clearTimeout(emgOverTimer);
   emgOverTimer = setTimeout(function() {
    emgOverTimer = 0;
    $(currentElement).addClass('emg-fluid-bring-front');
    $overlay.addClass('emg-fluid-anim-overlay');
    $overlay.data('statuson', true);
   }, 1000);

  } else if (action == 'close') {
    window.clearTimeout(emgOverTimer);
    emgOverTimer = 0;
    console.log(1);
    $overlay.removeClass('emg-fluid-anim-overlay');
    $overlay.data('statuson', false);
    $('.emg-fluid-header').find('.emg-fluid-bring-front').removeClass('emg-fluid-bring-front');
  }
}

简化实时示例:

// Scoping function so we don't create any globals
(function() {
  "use strict"; // Strict mode is almost always a good idea

  // Handlers to simulate calls to our function
  document.getElementById("btnOpen").onclick = function() {
    emgFluidOverlayShow('open');
  };
  document.getElementById("btnClose").onclick = function() {
    emgFluidOverlayShow('close');
  };
  
  // Timer handle
  var emgOverTimer = 0;
  
  // Function
  function emgFluidOverlayShow(action) {
    if (action == 'open') {
      clearTimeout(emgOverTimer);
      emgOverTimer = setTimeout(function() {
        emgOverTimer = 0;
        document.getElementById("overlay").style.display = "";
      }, 1000);
    } else if (action == 'close') {
      clearTimeout(emgOverTimer);
      emgOverTimer = 0;
        document.getElementById("overlay").style.display = "none";
    }
  }

})();
<input type="button" id="btnOpen" value="Open">
<input type="button" id="btnClose" value="Close">
<div id="overlay" style="display: none">I'm the overlay</div>

请注意,使用无效句柄调用clearTimeout是无操作,并且0根据定义是无效句柄,因此我们不需要围绕clearTimeout调用进行保护。 (当然,如果你愿意,可以添加它们。)

旁注:除非您的代码隐藏了window变量,否则没有技术原因可以为setTimeout加上前缀window.(您可能会为强调或类似做法)。 windowsetTimeout都是全局变量,JavaScript引擎必须像查找window一样难以找到(例如,链接所有包含范围),就像查找setTimeout一样等等。