setTimeout and this binding
除了切换类之外,我对使用 jquery 不是很熟悉。也就是说,我会尽量解释我的问题。我有三个div。单击其中一个后,另外两个应该翻转 90 度,然后将它们的高度降低到 0
我向 youTube 上传了一个简短的动画,向您展示最终动画的外观
https://youtu.be/4ImmHJ04d0w
所以我过于复杂的脚本现在看起来是这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // 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() { \t\t\t$('[class^=review--]').not(this).addClass('review__hidden review__square');\t \t\t\t$('.review--2 ,.review--3, .review--4').removeClass('review__hidden');\t\t\t\t\t \t\t}); \t\t// Animation \t\t$('.review--1').on('click', function() { \t\t\t \t\t\t$('.review--2 ,.review--3, .review--4').addTemporaryClass('animate-in', 500); \t\t\tsetTimeout(function() { \t\t$('.review--2 ,.review--3, .review--4').addClass('flip') \t\t\t}, 500); \t\t\t\t\t\t\t\t \t\t}); \t\t$('.review--2 ,.review--3, .review--4').on('click', function() { \t\t\t$(this).removeClass('review__square'); \t\t\t$('.review--2 ,.review--3, .review--4').not(this).addTemporaryClass('animate-out', 500); \t\t\tvar that = $(this); \t\t\tsetTimeout(function() { \t\t$('.review--2 ,.review--3, .review--4').not(that).removeClass('flip').addClass('review__hidden') \t\t\t}, 500); \t\t \t\t\t}); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | .review--button { \toverflow: hidden; \tcolor: #aa7f6f; \twidth: 100%; \tfloat: left; \theight: 50px; \tbackground-color: lightgrey; } .review__square { \tmargin: 6px 3px; \twidth: 190px; \theight: 190px; \ttext-align: center; \ttransform: rotateY(90deg); \tperspective: 80px; \t-webkit-perspective: 80px; \t/* transition: height .5s ease, transform .3s ease; */ } .review__hidden { \theight: 0; \tmargin: 0; \ttransform: rotateY(90deg); } .animate-in { \tanimation: flip-in .5s forwards; } @keyframes flip-in { \tfrom {transform: rotateY(90deg);} \tto {transform: rotateY(0);} } .animate-out { \tanimation: flip-out .5s forwards; } @keyframes flip-out { \tfrom {transform: rotateY(0);} \tto {transform: rotateY(90deg);} } .flip { \ttransform: rotateY(0); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> \t\t\t\t1 \t\t\t \t\t\t \t\t\t\t2 \t\t\t \t\t\t \t\t\t\t3 \t\t\t \t\t\t \t\t\t\t4 \t\t\t \t\t\t \t\t\t\t5 \t\t\t \t\t\t \t\t\t\t6 \t\t\t \t\t\t \t\t\t\t7 \t\t\t |
问题(除了我糟糕的代码)是 .not(this) 在超时内不起作用。有人可以告诉我怎么做吗?或者甚至更好地告诉我如何缓解我糟糕的代码:)
您是否像这样在
1 | var self = this; |
然后您可以在
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)...
如果包含
作为对象实例的方法或属性(通过实例变量):
1 2 3 4 5 6 | var o = new Object(); //"this" will be bound to the"o" object instance // while"someProperty" and"someMethod" code executes o.someProperty = someValue; o.someMethod(); |
通过
1 2 3 4 | //"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); |
注意:调用回调函数(即事件处理程序)时,会在触发事件时隐式调用处理程序。在这些情况下,负责触发事件的对象成为绑定到
的对象
此外,几个
1 2 3 4 5 | 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 ] ) |
如果其他场景都不适用,则发生默认绑定。
3a。
3b.没有
** 注意:使用
说了这么多,我不知道你为什么需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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"); }); }); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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%; } |
1 2 3 4 5 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> I'm DIV 1 I'm DIV 2 I'm DIV 3 |
虽然 Scott Marcus 很好地解释了调用方法如何由于某种原因改变其
直接从 MDN 引用
An arrow function does not create its own
this context, sothis has the original meaning from the enclosing context.
所以为了扩展马库斯的很好的答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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"); }); }); }); |
正如马库斯在评论中指出的,箭头函数不是在您希望动态绑定
无论哪种方式,它都是工具带和所有其他工具的另一个工具,
也许吧,你应该使用这个链接吗?
1 2 3 4 5 6 7 8 9 10 11 12 | $('.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); }); }); |