0

次の問題があります。ボックス内の画像をアニメーション化するための単純なプラグインjqueryカルーセルを作成しています。しかし、OOを使用してプラグインをビルドするという次の問題に遭遇しました。これを使用して、オブジェクトを参照します。

ただし、関数の1つはjqueryのanimateメソッドを使用します。そして、これを再帰的に実行したいと思います。アニメーションは一定だからです。ただし、コールバック関数jquery animateでは、これはオブジェクトアニメーションを参照し、プラグイン自体の実行で作成されたオブジェクトではありません。アニメーションで関数コールバックオブジェクトを呼び出すにはどうすればよいですか?アニメーションラインコードの直前に関数run()を呼び出すことを解決しようとしましたが、エラーが発生します:Uncaught RangeError:最大呼び出しスタックサイズを超えました

run関数をアニメーションコールバックに入れると、他のエラーが発生します:

this.wraper.animate(
                   {top : '-='+image_height},
                        this.config.speed,
                        this.run()
                   )

また

 this.wraper.animate(
                   {top : '-='+image_height},
                        this.config.speed,
                        function(){
                            this.run();
                        }
                   )

これはthis.wraperオブジェクトへの参照であり、関数オブジェクトへの参照ではないため、説明がわかりにくいようです。

コードは次のとおりです。

  (function($){

carouselClass = function (el, opts) {
        this.id = $(el).attr("id");        
        this.i = 0;                     
        this.config = opts;
        this.wraper;
        this.count = 0;
        this.flag = true;
        this.init = function() {
            // variables        
            var img = $("#"+this.id).find("img");       
            this.count = img.length;


            //adiciona css necessário a div wrapper
            $("#"+this.id).css("position","relative");
            $("#"+this.id).css("overflow","hidden");


            $("#"+this.id).append("<div></div>");       
            this.wraper = $("#"+this.id).find("div");           


            //definições css da div wrapper
            this.wraper.css("position","absolute");
            this.wraper.css("right","0px");                 
            var direction = this.config.direction;
            var container = this.wraper;
            //adiciona as imagens ao novo container
            img.each(function(){
                if(direction == "left" || direction == "right")
                    $(this).css("float", direction)

                $(this).css("display", "block");
                container.append($(this));                                          
            }); 

            //seta a largura e altura do wraper conforme a direção
            if(direction == "left" || direction == "right")
            {
                this.wraper.width((img.width()*this.count));
                this.wraper.height(img.height());
            }
            else
            {
                this.wraper.height((img.height()*this.count));
                this.wraper.width(img.width());
            }

            this.run(); 
        }           



        this.run = function()
        {                   
            if(this.config.direction == "top")
            {
                height = this.wraper.height();              
                image_height = height/this.count;                   
                for(j = 0; j < (this.count-1); j++)
                {
                    this.wraper.animate(
                        {top : '-='+image_height},
                        this.config.speed

                    )

                }
                this.wraper.animate(
                    {top:'0px'},
                    this.config.speed   
                );
                                    //my problem is this call to function recursive
                this.run();             
            }

            if(this.config.direction == "bottom")
            {
                height = this.wraper.height();              
                image_height = height/this.count;                   
                for(j = 0; j < (this.count-1); j++)
                {
                    this.wraper.animate(
                        {bottom : '-='+image_height},
                        this.config.speed

                    )

                }
                this.wraper.animate(
                    {bottom:'0px'},
                    this.config.speed   
                );
                                    //my problem is this call to function recursive
                this.run();         
            }


            if(this.config.direction == "left")
            {
                width = this.wraper.width();                
                image_width = width/this.count;                 
                for(j = 0; j < (this.count-1); j++)
                {
                    this.wraper.animate(
                        {left : '-='+image_width},
                        this.config.speed

                    )

                }
                this.wraper.animate(
                    {left:'0px'},
                    this.config.speed   
                );
                                    //my problem is this call to function recursive
                this.run();         
            }

            if(this.config.direction == "right")
            {
                width = this.wraper.width();                
                image_width = width/this.count;                 
                for(j = 0; j < (this.count-1); j++)
                {
                    this.wraper.animate(
                        {right : '-='+image_width},
                        this.config.speed

                    )

                }
                this.wraper.animate(
                    {right:'0px'},
                    this.config.speed   
                );
                                    //my problem is this call to function recursive
                this.run();         
            }

        }           
    };

$.fn.carousel = function(options)
{

    var opts = $.extend({}, $.fn.carousel.defaults, options);
    return this.each(function () {
            var instance = new carouselClass($(this), opts);
            /**********Start the carousel ***********/
            instance.init();                
        });

    $.fn.carousel.defaults = {
        'direction': "left",
        'speed': 3000
    };      

}    

 })(jQuery);

この方法で呼び出すと、プラグインは機能しますが、i varに設定した回数だけであり、カルーセルが継続的に変更されることを望みます。

this.prepare = function()
        {
            this.i++;

            if(this.i < 3)
            {                   

                    this.run();
            }                           
        }

this.run = function()
        {                   
            if(this.config.direction == "top")
            {
                height = this.wraper.height();              
                image_height = height/this.count;                   
                for(j = 0; j < (this.count-1); j++)
                {
                    this.wraper.animate(
                        {top : '-='+image_height},
                        this.config.speed

                    )

                }
                this.wraper.animate(
                    {top:'0px'},
                    this.config.speed   
                );
                this.prepare();             
            }
                 }
4

3 に答える 3

0

使ってみて$.proxy()

this.wraper.animate(
                   {top : '-='+image_height},
                        this.config.speed,
                        $.proxy(function(){
                            this.run();
                        }, this)
                   )
于 2012-06-18T22:45:06.870 に答える
0
this.setAnimation=function(state){
        var obj=this;
        if(state)obj.animationID=setInterval(function() { 
            obj.run();
            },obj.config.speed);
        else {
            clearInterval(obj.animationID);
            }
        };

このようなものをお探しですか?

setAnimation(true)//start Animation
于 2012-06-18T22:46:33.837 に答える