0

I've got this piece of script here, where I'd like to slide up my ul element, then after the slide up executed, I'd like to remove the "open" class for CSS reasons. What am I doing wrong?

jQuery(this).parent().children("ul").slideUp(500);
setTimeout(function(){
  var elementToRemove = jQuery(this).parent();
  elementToRemove.removeClass("open");
}, 500);
sklrboy
  • 441
  • 1
  • 6
  • 15
  • If you're intending to call the anonymous function after the slideUp animation has completed, use a callback instead of hardcoding a `setTimeout` timer. If you update your animation duration in the future, you wouldn't have to update `500` in two places. – Terry Feb 05 '17 at 11:20
  • Possible duplicate of [How does the "this" keyword work?](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Andreas Feb 05 '17 at 11:21

3 Answers3

2

this inside you callback function refers to the global object and not the event target.

Two solutions:

Use arrow functions (which preserve the this context):

jQuery(this).parent().children("ul").slideUp(500);
setTimeout(() => {
  var elementToRemove = jQuery(this).parent();
  elementToRemove.removeClass("open");
}, 500);

Or save a link to the this object:

jQuery(this).parent().children("ul").slideUp(500);
let that = this;
setTimeout(function(){
  var elementToRemove = jQuery(that).parent();
  elementToRemove.removeClass("open");
}, 500);
Sirko
  • 72,589
  • 19
  • 149
  • 183
2

Solution 1

Use bind to pass the context to the function

jQuery(this).parent().children("ul").slideUp(500);

var func = function(){
  var elementToRemove = jQuery(this).parent();
  elementToRemove.removeClass("open");
}
setTimeout(func.bind(this),500);

Solution 2

jQuery(this).parent().children("ul").slideUp(500);
var self = this;
setTimeout(function(){
  var elementToRemove = jQuery(self).parent();
  elementToRemove.removeClass("open");
}, 500);
Vladu Ionut
  • 8,075
  • 1
  • 19
  • 30
2

jQuery animations allow for an additional optional pararameter (a callback) called complete in the docs that will be executed once the animation is done. You can use it like this:

jQuery(this).parent()
            .children("ul")
            .slideUp(500, function(){
                var elementToRemove = jQuery(this).parent();
                elementToRemove.removeClass("open");
            });
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73