David Allen
David Allen

Reputation: 1163

jQuery run parent function within animate

I'm making a plugin for jQuery and I need to rerun the same function after some animation has finished. I'm trying to do this using setTimeout() in the animate function.

The code I'm struggling with is at the bottom is

jQuery(theslide).animate(theanimation,1000,function() {
        setTimeout('this.makemeslide()',3000)
})

the console error message is Uncaught TypeError: Object [object Window] has no method 'makemeslide' which makes seen because this is point at the animated object. But I dont know how to achieve my goal.

Here my full code

jQuery.fn.daSlider = function(options) {
    //Options
    var settings = $.extend( {
          'selector'         : 'slider',
          'width'      : 940,
          'height'     : 380
        }, options);

    //globals
    var sliderarray = [];
    var slidercount = 0;


    //Contruct
    this.construct = function()
    {
       jQuery('.slider .slide').each(function(){

              jQuery(this).css('display','none');
              sliderarray.push(this) ;

              jQuery(this).children().each(function(){
                    jQuery(this).css('display','none');
                    sliderarray.push(this) ;
                });
       });

      this.makemeslide();
    }
    //run the constuct

    this.makemeslide = function()
    {
      theslide = sliderarray[slidercount];
      slidercount++;

      way_to_slide = jQuery(theslide).attr('slide');

      slide_position =  jQuery(theslide).position();
      //console.log(slide_width);
      //console.log(slide_height);


      if(way_to_slide == 'right')
      {
        jQuery(theslide).css('left', slide_position.left + settings.width);
        theanimation = {'left' : '-='+settings.width};
      }
      if(way_to_slide == 'left')
      {
        jQuery(theslide).css('left', slide_position.left - settings.width);
        theanimation = {'left' : '+='+settings.width};
      }
      if(way_to_slide == 'up')
      {
        jQuery(theslide).css('top', slide_position.top - settings.height);
        theanimation = {'top' : '+='+settings.height};
      }
      if(way_to_slide == 'down')
      {
        jQuery(theslide).css('top', slide_position.top + settings.height);
        theanimation = {'top' : '-='+settings.height};
      }
      if(way_to_slide == 'fade')
      {
        jQuery(theslide).css('opacity', 0);
        theanimation = {'opacity' : 1};
      }

      jQuery(theslide).css('display','block') ;
      jQuery(theslide).animate(theanimation,1000,function(){setTimeout('this.makemeslide()',3000)})

    }
    this.construct();

};

Upvotes: 0

Views: 96

Answers (2)

El Hocko
El Hocko

Reputation: 2606

this is because this in javascript is not the same as i Java. this is the window-object in this case.

you can use closures to avoid this problem:

function Object(){
    self=this;
    this.inner = function(){


     setTimeout(function(){
        alert(self);
        alert(this);
     },100);
    }
}

var o = new Object();
o.inner();

Note that the second alert will show you the window-object, not the o-object

Upvotes: 0

Bergi
Bergi

Reputation: 664434

Do never use setTimeout with code strings to be evaled! Also, your this reference will not be the one from the parent function.

var plugin = this;
jQuery(theslide).animate(theanimation, 1000, function() {
    // "this" references theslide element
    setTimeout(function() {
        // "this" references the global object (window)
        plugin.makemeslide();
    }, 3000);
});

Btw, instead of a independent timeout you might want to use jQuery's delay method with a callback.

Upvotes: 1

Related Questions