Javascript原型属性在函数中返回undefined

时间:2015-01-11 17:50:17

标签: javascript jquery css prototype prototypal-inheritance

使用原型继承创建图像旋转器,我在控制台显示中不断收到错误:TypeError:this.curPhoto is undefined          this.curPhoto.removeClass('以前&#39); 我把它放在用于切换重叠div的位置的函数之一的回调函数中(堆栈在彼此之下)这是代码:

    <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
    <script src='ImageRotatorOOP.js' type='text/javascript'> </script>
    <script type='text/javascript'>
    $('document').ready(function() {
    setInterval('rotateImages()', 2000);
    });

    function rotateImages() {
    var imageRotator = new ImageRotator($('#photoShow'));
    if(imageRotator.nextPhoto.length == 0) {
        imageRotator.nextPhoto = imageRotator.container.children().first();
    }

    imageRotator.stackImages();
    }
    </script>

    </head>
  <body>
  <h1> Image Rotator </h1>
  <div id='photoShow'>
<div class='current'>
    <img src='images/RoyMustang.jpg' alt='Roy Mustang' />
</div>
<div>
    <img src='images/nhk.png' alt='Welcome to the NHK' />
</div>
<div>
    <img src='images/dragonball_z.jpg' alt='Dragonball Z'/>
</div>
</div>
</body>
</html>

和.js文件

    var ImageRotator = function(container) {
this.container = container;
this.curPhoto = this.container.find('div.current');
this.nextPhoto = this.curPhoto.next('div'); 
}

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        this.curPhoto.removeClass('previous');
    });
}

这是css文件

   #photoShow img {
    width: 400px;
    height: 300px;  
    }

    #photoShow div {
    position: absolute;
    z-index: 0;
    }

    #photoShow div.previous {
    z-index: 1;
    }

    #photoShow div.current {
    z-index: 2;
    }

2 个答案:

答案 0 :(得分:1)

在动画完成功能中,this的值将是DOM对象的动画,而不是您的ImageRotator对象。您可以通过执行以下操作来解决该问题:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    var self = this;
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000, function() {
        self.curPhoto.removeClass('previous');
    });
}

注意:这是回调函数的常见问题,因为Javascript中的每个函数调用都为this设置了一个新值,所以除非动画回调专门用于将this的值设置为你的值想要,它将被设置为其他东西。在嵌入式回调之前将值保存到局部变量是常见的解决方法。你也可以使用.bind()做类似的事情,但是为你做。

以下是使用.bind()的示例:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000, function() {
        this.curPhoto.removeClass('previous');
    }.bind(this));
}

答案 1 :(得分:1)

问题出在这段代码中:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        this.curPhoto.removeClass('previous');
    });
}

在行上,this.curPhoto.removeClass('previous');this不是引用ImageRotator实例而是引用jQuery对象。

您可以通过在上面的闭包中保存this的值来解决此问题。

ImageRotator.prototype.stackImages = function() {
    var that = this;
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        that.curPhoto.removeClass('previous');
    });
}