开发者

Jquery animate problem with potential variable scope issue?

开发者 https://www.devze.com 2023-03-26 12:26 出处:网络
I\'ve written an example of my problem, for some reason (which I don\'t seem to fully understand I guess), my variables are losing scope. I\'m trying to animate several things on the screen, once they

I've written an example of my problem, for some reason (which I don't seem to fully understand I guess), my variables are losing scope. I'm trying to animate several things on the screen, once they've reached their destination the 'complete' function within animate() kicks in, this is meant to basically delete the dom element as well as a couple other functions that are meant to be delayed within it. A good way to think of it is a gun firing, do the damage when the bullet hits and not before, and the damage the bullet does is tied into the animation itself.

As I mentioned in my first sentence, I've written an example to demonstrate exactly what I mean. I'll also paste in the console.log output that came with it and give a summary of what it shows.

I've placed the example in jsbin, as it should be easier for you guys to see (I hope -- I've never used that stuff before). For my example I just did an animation of a square block filling, and some squares flying near it. When those squares reach its destination, it empties some out of the 'Jar' and resets its animation, then it removes itself from the dom.

http://jsbin.com/ihozil/2

Here's the console.log text from chrome:

Set Height to: 30px
Testing.Start( [Object] )
Setup #I63326848.animate()
Setup #I22596539.animate()
Setup #I14561405.animate()
Setup #I57372916.animate()
Setup #I31994195.animate()
OnComplete for :I63326848
Set Height to: 30.6px
OnComplete for :I14561405
Set Height to: 33px
OnComplete for :I57372916
Set Height to: 34.2px
OnComplete for :I31994195
Set Height to: 36px
OnComplete for :I63326848
Set Height to: 36.6px
Finished filling

As you can see from the lo开发者_JAVA技巧g above, #I22596539 (2nd one) was set up, however when it came to the OnComplete methods, it did not fire, all the others did and #I63326848 fired twice (1st method setup). I've also noticed that when I remove the .stop() part of the chain on the squared box (#Jar), that these problems do not happen. However that is needed so I don't end up with several animations trying to fill the jar at the same time. I've also noticed that it's ALWAYS the second animation to be set up that does this.

So I'm not entirely sure if it's variables losing scope, else surely this would happen to the others, I've sent the last couple of days trying to suss this one out and I've hit my road block. I've ran out of things to try to fix it. You guys are my last hope!

function Jar() {
   this._iAmount = 50;
   this._iMaxAmount = 100;
   this._iRefillRate = 5;

   return this;
}
Jar.prototype = {
   ReduceAmount: function( m_iAmount ) {
      this._iAmount -= m_iAmount;

      if( this._iAmount < 0 ) {
         this._iAmount = 0;
      }
      return;
   },
   StartFill: function() {
      var iHeight = ( 60 - ( 60 * this._iAmount / this._iMaxAmount ) );

      console.log( "Set Height to: "+iHeight+"px" );
      jQuery( '#Jar' ).css( 'height', iHeight+'px' );

      if( iHeight < 60 ) {
         var iMillisecondsTilMax = ( ( this._iMaxAmount - this._iAmount ) / this._iRefillRate ) * 1000;

         jQuery('#Jar').stop().animate({height: '0px'}, iMillisecondsTilMax, function() { console.log( "Finished filling" ); } );
      }
      return;
   }
};

var Testing = {
   Start: function( m_oJar ) {
      console.log( "Testing.Start( [Object] )" );
      for( var iLoop = 0; iLoop < 5; iLoop++ ) {
         var elNewDiv = document.createElement('div');

         var iRandomValue = Math.round( 1 + ( Math.random() * ( 99999999 - 1 ) ) );
         var iAmount = Math.round( 1 + ( Math.random() * ( 5 - 1 ) ) );
         var strID = "I"+iRandomValue;

         elNewDiv.setAttribute( 'id', strID );
         elNewDiv.style.border = 'solid 1px red';
         elNewDiv.style.position = "absolute";
         elNewDiv.style.height = '200px';
         elNewDiv.style.width = '200px';
         elNewDiv.style.left = '0px';
         elNewDiv.style.top = '0px';

         document.body.appendChild( elNewDiv );

         this.Animate( m_oJar, strID, iAmount );
      }
      return;
   },
   Animate: function( m_oJar, m_strID, m_iAmount ) {
         console.log( "Setup #"+m_strID+".animate()" );
         jQuery( '#'+m_strID ).animate({ width: '30px', height: '30px', top: '100px', left: '200px' }, {
            duration: 1000,
            queue: false,
            easing: 'linear',
            complete: function() {
               console.log( "OnComplete for :"+m_strID );
               m_oJar.ReduceAmount( m_iAmount );
               m_oJar.StartFill();

               jQuery( '#'+m_strID ).remove();
            }
         });
    }
};
jQuery(document).ready( function() {
   var oJar = new Jar();

   oJar.StartFill();

   Testing.Start( oJar );
});


I don't have a great answer, but I think this might be a jQuery bug. I have been able to work around the issue by modifying the StartFill method, or just not calling it the first time in the ready() function. I've also seen it go away when I use the debugger which leans towards some sort of timing issue...possibly in jQuery, possibly in the browser. I've not tested this on anything other than Chrome so it's hard to be sure. However I don't think there is anything wrong with the logic in your code provided.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号