首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >全局变量,延迟和这个

全局变量,延迟和这个
EN

Stack Overflow用户
提问于 2019-07-10 10:17:17
回答 1查看 121关注 0票数 1

我编写了这个简单的机制来向菜单中添加一些交互性和效果:

代码语言:javascript
运行
复制
var $body = $('body');
var $theNav = $('.the-nav-wrapper');
var $theMenuBar = $('.the-menu-bar');
var $menuOpener = $('.menu-opener');

$menuOpener.on('click', function() {
   $(this).toggleClass('becomeMenuCloser textAppears');     
   $theNav.toggleClass('open');
   $body.toggleClass('preventScroll');
   $theMenuBar.toggleClass('bringOnTop');
   $(this).toggleText('Menu', 'Close');    
});

这个很好用。

按照编写菜单代码的思路,我决定在类becomeMenuCloser textAppears切换之间添加一个延迟,以便首先切换becomeMenuCloser,然后在短时间延迟后切换textAppears

我对负责切换类的特定代码行进行了如下修改:

$(this).toggleClass('becomeMenuCloser').delay(1300).toggleClass('textAppears');

这不管用。它同时切换两个类。然后我试了一下:

代码语言:javascript
运行
复制
$(this).toggleClass('becomeMenuCloser').promise().done(function(){
   $(this).toggleClass('textAppears'); 
});

这也不起作用。然后我试了一下:

代码语言:javascript
运行
复制
$(this).toggleClass('becomeMenuCloser');
setTimeout(function() {
   $(this).toggleClass('textAppears'); 
}, 610);

这也不起作用,因为代码从未进入setTimeout,随后也从未切换到第二个类。

经过尝试和错误(以及一些挫折和思考),我意外地发现,我的问题的解决方案是删除$(this)并用缓存的变量$menuOpener替换它,如下所示:

代码语言:javascript
运行
复制
$(this).toggleClass('becomeMenuCloser')
setTimeout(function() {
  $menuOpener.toggleClass('textAppears'); 
}, 310);

这个很管用。

的问题是:

1)为什么在这种情况下$(this)是问题所在?我真的很想了解这里丢失的线索。

2)我也不明白为什么使用$menuOpener解决问题。

3)当将元素存储为全局变量时,是否应该只使用全局变量而忽略$(this)

嘿,谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-10 10:51:22

这是因为有不同的上下文(这)。

检查以下示例:Jsfiddle(单击div文本并检查控制台)

示例1:在第一个函数中,第一个console.log打印

上下文1 id:foo

而第二张指纹

上下文2 id:未定义

由于上下文切换(不再指向dom元素)。

代码语言:javascript
运行
复制
//example 1
    function context() {
      var div = $("#foo");
      div.on('click', function() {
        $(this).toggleClass('becomeMenuCloser');
        console.log("context 1 id:" + this.id);//foo
        setTimeout(function() {
          console.log("context 2 id:" + this.id);//undefined
          div.toggleClass('textAppears');
        }, 610);
      })
    }
    context();

现在,在第二个示例中,我们使用箭头函数(()=>)来保留上下文,因此在超时函数中也使用相同的"this“实例,因此控制台两次打印正确的id。

在第一个函数中,第一个console.log打印

上下文1 id:foo

第二个也一样

上下文2 id:foo

代码语言:javascript
运行
复制
//example 2
function context2() {
  var div = $("#foo2");
  div.on('click', function() {
    $(this).toggleClass('becomeMenuCloser');
    console.log("context 1 id:" + this.id);//foo
    setTimeout(() => {
      console.log("context 2 id:" + this.id);//foo
      div.toggleClass('textAppears');
    }, 610);
  })
}
context2();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56968585

复制
相关文章

相似问题

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