setTimeout和这个绑定

时间:2016-12-11 22:05:53

标签: javascript jquery

除了切换类之外,我不太熟悉使用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);
}

<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>
&#13;
&#13;
&#13;

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

3 个答案:

答案 0 :(得分:3)

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

您是否在this之前缓存了setTimeout对象参考:

var self = this;

然后,您可以在self中引用setTimeout,这样就可以了。

  

这是一个清单,您可以通过该清单了解this将绑定的内容   到(您的方案是#3,您可以阅读更多相关信息 here   在“ 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. 通过.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);
    

    注意:当调用回调函数(即事件处理程序)时,触发事件时会对处理程序进行隐式调用。在这些情况下,负责触发事件的对象将成为绑定到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绑定到全局对象

  4. **注意:使用this也可能会影响eval()绑定,但作为一般的最佳做法,应避免使用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%;
    }
    <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>

答案 1 :(得分:0)

可能是,你应该使用链接吗? 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); 

  });
});

答案 2 :(得分:0)

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

直接从MDN

报价
  

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

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

this

正如Marcus在评论中指出的那样,箭头函数不是你希望动态绑定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"); }); }); }); 的工具,但是如果你发现你的自己必须经常使用this因为你的回调正在为你的上下文重新绑定当你不希望它时,箭头函数可能会有用。

无论哪种方式,它是工具带的另一个工具,以及所有这些,