setTimeout和这个绑定 [英] setTimeout and this binding
问题描述
除了切换类之外,我不太熟悉使用jquery。也就是说,我会尽力解释我的问题。我有三个div。点击其中一个之后,另外两个应该翻转90度并且AFTERWARDS将它们的高度降低到0
I am not very familiar with using jquery other than toggling classes. That said, I will try to explain my problem as good as possible. I have three divs. After clicking one of them, the other two should should flip by 90degs and AFTERWARDS reduce their height to 0
我向youTube上传了一个简短的动画来向你展示最终动画看起来像
https://youtu.be/4ImmHJ04d0w
I uploaded a short animation to youTube to show you how the final animation is meant to look like https://youtu.be/4ImmHJ04d0w
所以我过于复杂的脚本现在看起来像那样
So my overly complicated script looks like that at the moment
// 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);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="review--button review--1">
<i>1</i>
</div>
<div class="review--button review__square review--2 review__hidden">
<i>2</i>
</div>
<div class="review--button review__square review--3 review__hidden">
<i>3</i>
</div>
<div class="review--button review__square review--4 review__hidden">
<i>4</i>
</div>
<div class="review--button review__square review--5 review__hidden">
<i>5</i>
</div>
<div class="review--button review__square review--6 review__hidden">
<i>6</i>
</div>
<div class="review--button review__square review--7 review__hidden">
<i>7</i>
</div>
问题(在我糟糕的代码旁边)是.not(this)在Timeout中不起作用。有人可以告诉我怎么做吗?或者甚至更好地告诉我如何缓解我糟糕的代码:)
The problem (beside my poor code) is that the .not(this) doesn't work within the Timeout. Can somebody please tell me how to do this? Or even better tell me how my crappy code could be eased :)
推荐答案
this
对象绑定在JavaScript中是易失性的...也就是说,它并不总是指向同一个对象,并且它的绑定可以从一行代码更改为下一行代码。 如何调用包含单词的代码
确定它将绑定到哪个对象。
The this
object binding is volatile in JavaScript...that is, it doesn't always point to the same object and its binding can change from one line of code to the very next. How you invoke the code that contains the word this
determines what object it will bind to.
如果你在 setTimeout
之前缓存了你的这个
对象引用,那么:
Had you cached your this
object reference prior to the setTimeout
like this:
var self = this;
然后您可以参考 self
setTimeout
它会有效。
you could then refer to self
in the setTimeout
and it would have worked.
这是一个你可以遵循的清单知道
这个
将
绑定到(你的场景是#3,你可以阅读更多关于它 这里
下的 这个问题 部分)...
Here's a checklist that you can follow to know what
this
will bind to (your scenario is #3 and you can read more about it here under the "The "this" problem" section)...
如果代码包含调用此
:
-
作为对象实例的方法或属性(通过实例变量) ):
As a method or property of an object instance (through an instance variable):
var o = new Object();
// "this" will be bound to the "o" object instance
// while "someProperty" and "someMethod" code executes
o.someProperty = someValue;
o.someMethod();
通过 .call()
, .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);
注意:调用回调函数时(即事件处理程序),触发事件时会对处理程序进行隐式调用。在这些情况下,负责触发事件的对象成为绑定到此
的对象。
Note: When a callback function is invoked (i.e. event handler), there is an implicit call to the handler when the event is triggered. In these cases, the object responsible for triggering the event becomes the object bound to this
.
此外,有几个 Array.prototype
方法允许传递 thisObject
,这将在方法调用的持续时间内改变绑定:
Additionally, several Array.prototype
methods allow for a thisObject
to be passed which will alter the binding for the duration of the method call:
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 ] )
如果没有其他方案适用,则会发生默认绑定。
If none of the other scenarios apply, Default binding occurs.
3a。使用use strict
:此
是 undefined
3b。没有use strict
生效:此
绑定到Global对象
3b. Without "use strict"
in effect: this
binds to the Global object
**注意:此
绑定也会受到使用 eval的影响( )
,但作为一般的最佳做法,应避免使用 eval()
。
** NOTE: this
binding can also be affected by using eval()
, but as a general best practice, the use of eval()
should be avoided.
说了这么多,我不确定为什么你需要一个 setTimeout
(如果我理解你的场景正确的话):
Having said all that, I'm not sure why you need a setTimeout
at all (if I understood your scenario correctly):
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%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<div>I'm DIV 1</div>
<div>I'm DIV 2</div>
<div>I'm DIV 3</div>
</div>
这篇关于setTimeout和这个绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!