setTimeout和这个绑定

除了切换类之外,我不太熟悉使用jquery。 也就是说,我会尽力解释我的问题。 我有三个div。 点击其中一个之后,其他两个应该翻转90度并且AFTERWARDS将它们的高度减小到0

我向youTube上传了一个简短的动画,向您展示最终动画的外观如何看起来像https://youtu.be/4ImmHJ04d0w

所以我过于复杂的脚本现在看起来像那样

// Add Temporarily Class (function($){ $.fn.extend({ addTemporaryClass: function(className, duration) { var elements = this; setTimeout(function() { elements.removeClass(className); }, duration); return this.each(function() { $(this).addClass(className); }); } }); })(jQuery); $('.review--1').on('click', function() { $('[class^=review--]').not(this).addClass('review__hidden review__square'); $('.review--2 ,.review--3, .review--4').removeClass('review__hidden'); }); // Animation $('.review--1').on('click', function() { $('.review--2 ,.review--3, .review--4').addTemporaryClass('animate-in', 500); setTimeout(function() { $('.review--2 ,.review--3, .review--4').addClass('flip') }, 500); }); $('.review--2 ,.review--3, .review--4').on('click', function() { $(this).removeClass('review__square'); $('.review--2 ,.review--3, .review--4').not(this).addTemporaryClass('animate-out', 500); var that = $(this); setTimeout(function() { $('.review--2 ,.review--3, .review--4').not(that).removeClass('flip').addClass('review__hidden') }, 500); }); 
 .review--button { overflow: hidden; color: #aa7f6f; width: 100%; float: left; height: 50px; background-color: lightgrey; } .review__square { margin: 6px 3px; width: 190px; height: 190px; text-align: center; transform: rotateY(90deg); perspective: 80px; -webkit-perspective: 80px; /* transition: height .5s ease, transform .3s ease; */ } .review__hidden { height: 0; margin: 0; transform: rotateY(90deg); } .animate-in { animation: flip-in .5s forwards; } @keyframes flip-in { from {transform: rotateY(90deg);} to {transform: rotateY(0);} } .animate-out { animation: flip-out .5s forwards; } @keyframes flip-out { from {transform: rotateY(0);} to {transform: rotateY(90deg);} } .flip { transform: rotateY(0); } 
  
1
2
3
4
5
6
7

问题(在我糟糕的代码旁边)是.not(this)在Timeout中不起作用。 有人可以告诉我怎么做吗? 或者甚至更好地告诉我如何缓解我糟糕的代码:)

this对象绑定在JavaScript中是易失性的……也就是说,它并不总是指向同一个对象,并且它的绑定可以从一行代码更改为下一行代码。 如何调用包含单词的代码,以确定它将绑定到哪个对象。

你是否在setTimeout之前缓存了this对象引用,如下所示:

 var self = this; 

然后你可以在setTimeout引用self ,它会起作用。

这是一个清单,您可以按照它来了解它将绑定到什么(您的方案是#3,您可以在“ The”这个“问题 ”部分下面阅读更多关于它的信息 )…

如果调用包含this的代码:

  1. 作为对象实例的方法或属性(通过实例变量):

     var o = new Object(); // "this" will be bound to the "o" object instance // while "someProperty" and "someMethod" code executes o.someProperty = someValue; o.someMethod(); 
  2. 通过.apply() .bind()Array.prototype.fn调用:

     // "this" will be bound to the object suppled as the "thisObjectBinding" someFunction.call(thisObjectBinding, arg, arg); someFunction.apply(thisObjectBinding, [arg, arg]); var newFunc = someFunction.bind(thisObjectBinding, arg, arg); 

    注意 :当调用回调函数(即事件处理程序)时,在触发事件时会对处理程序进行隐式调用。 在这些情况下,负责触发事件的对象将成为绑定this对象的对象。

    另外,几个Array.prototype方法允许传递thisObject ,这将在方法调用的持续时间内改变绑定:

     Array.prototype.every( callbackfn [ , thisArg ] ) Array.prototype.some( callbackfn [ , thisArg ] ) Array.prototype.forEach( callbackfn [ , thisArg ] ) Array.prototype.map( callbackfn [ , thisArg ] ) Array.prototype.filter( callbackfn [ , thisArg ] ) 
  3. 如果没有其他方案适用,则发生默认绑定。

    3A。 实际上使用"use strict"thisundefined

    3B。 没有"use strict"生效: this将绑定到Global对象

**注意:使用eval()也会影响this绑定,但作为一般的最佳实践,应避免使用eval()

说了这么多,我不确定为什么你需要一个setTimeout (如果我理解你的场景正确):

 var divs = document.querySelectorAll("div:not(#parent)"); divs.forEach(function(div){ div.addEventListener("click", function(){ var self = this; // get other two divs, not this one var $otherDivs = $(divs).not(this); // Fade them out: $otherDivs.fadeOut(function(){ // JQuery animations accept a callback function to run when the animation is complete $(self).addClass("clickedDiv"); }); }); }); 
 #parent { width:350px; border: 0; background:inherit;} div { width:100px; height:100px; background:#ff0; text-align:center; float:left; border:1px solid black; } .clickedDiv { background:#f99; width:100%; } 
  
I'm DIV 1
I'm DIV 2
I'm DIV 3

可能是,你应该使用这个链接? var self= $(this)

 $('.review--2 ,.review--3, .review--4').on('click', function() { $(this).removeClass('review__square'); $('.review--2 ,.review--3, .review--4').not(this).addTemporaryClass('animate-out', 500); var self = $(this); setTimeout(function() { $('.review--2 ,.review--3, .review--4').not(self).removeClass('flip').addClass('review__hidden') }, 500); }); }); 

虽然斯科特马库斯提供了一个非常好的解释,说明如何调用方法可以更改其对象由于某种原因,他不想更新他的答案,包括如何使用箭头函数调用方法影响this对象。

直接从MDN引用

箭头函数不会创建自己的this上下文,因此this具有封闭上下文的原始含义。

所以扩展马库斯的非常好的答案

 var divs = document.querySelectorAll("div:not(#parent)"); divs.forEach(function(div){ div.addEventListener("click", function(){ // get other two divs, not this one var $otherDivs = $(divs).not(this); // Fade them out: $otherDivs.fadeOut(() => { // JQuery animations accept a callback function to run when the animation is complete $(this).addClass("clickedDiv"); }); }); }); 

正如Marcus在评论中指出的那样,箭头函数不是你想要动态绑定的工具,但如果你发现你的自己必须使用var self = this通常因为你的回调正在重新绑定它的上下文当你不想要它时,箭头function可能会有用。

无论哪种方式,它的工具带的另一个工具和所有,