首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设置超时(如果为真),取消它(在其他情况下)

设置超时(如果为真),取消它(在其他情况下)
EN

Stack Overflow用户
提问于 2015-11-04 10:37:00
回答 1查看 641关注 0票数 1

因此,我在鼠标结束/鼠标退出事件上调用这个函数。首先我用'open‘参数调用它,然后用'close’参数调用它(鼠标退出)。

我想在覆盖显示中添加一个延迟,并在超时到期之前用“close”调用该函数的取消显示。

在没有超时的情况下,函数在鼠标退出时立即进入“关闭”分支,超时事件在超时结束之前不会运行if,因此window.clearTimeout(emgOverTimer);没有机会发挥它的神奇作用。

代码语言:javascript
运行
复制
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');
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-04 10:43:53

您的emgOverTimer变量是函数中的局部变量,因此在随后调用该函数时,它很自然地是一个与上一次调用使用的变量不同的变量。

将其移到包含的作用域,以便所有emgFluidOverlayShow函数调用都使用相同的变量:

代码语言:javascript
运行
复制
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')之后插入此逻辑。

代码语言:javascript
运行
复制
window.clearTimeout(imgOverTimer);

并清除计时器回调中的定时器句柄以及close情况:

代码语言:javascript
运行
复制
imgOverTimer = 0;

所以,所有这些都是:

代码语言:javascript
运行
复制
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');
  }
}

简化的动态示例:

代码语言:javascript
运行
复制
// 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";
    }
  }

})();
代码语言:javascript
运行
复制
<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变量进行阴影,否则使用window.作为前缀没有任何技术原因(可能是为了强调或类似的目的)。windowsetTimeout都是全局的,JavaScript引擎必须努力找到window (例如,将所有包含的作用域链接起来),就像查找setTimeout一样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33519626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档