1

我正在为我的网站编写简单的滑块。此滑块包含列表项。我想使用 OOP 方法。

我的实际代码:

var miniSlider = function(objId)
    {
        this.obj = $("#" + objId);
        this.obj.settings = [];
        this.obj.settings['items'] = $('ul li', this.obj).length;

        this.pagerNext = this.obj.find("i.next");
        this.pagerPrev = this.obj.find("i.prev");
        this.pagerNext.on("click", function() {
        alert(this.obj.settings['items']);
        });
    };

我可以调用其他一些滑块(是的,这就是我引入一个类的原因):

miniSlider("mini-slider");

问题是当我在 jQuery 中时 this.pagerNext.on("click", function() { }); 不再是我的对象,而是 - 它已成为点击元素。点击后如何访问 this.obj.settings(并支持多滑块)?

编辑:

这是与 SOF 社区合作创建的完整代码:)

var MiniSlider = function(objId)
{
    this.obj = $("#" + objId);

    this.obj.settings = {
        items: $("ul li", this.obj).length,
        autoChangeTime: 8000
    };
    this.obj.activeElement = null;

    this.pagerNext = this.obj.find("i.next");
    this.pagerPrev = this.obj.find("i.prev");

    var self = this;

    this.pagerNext.on("click", function() {

        self.obj.activeElement = $('li.active', self.obj);

        if(self.obj.settings.items > 0)
        {
            if(self.obj.activeElement.is(':last-child')) 
            { 
                $('li.active', self.obj).removeClass('active');
                $('li', self.obj).first().addClass('active');
            } 
            else 
            {
                self.obj.activeElement.next().addClass('active').prev().removeClass('active');
        }
    }
    });
    this.pagerPrev.on("click", function() 
    {
        self.obj.activeElement = $('li.active', self.obj);

        if(self.obj.settings.items > 0)
        {
            if(self.obj.activeElement.is(':first-child')) 
            { 
                self.obj.activeElement.removeClass('active');
                $('li', self.obj).last().addClass('active');
            } 
            else 
            {
                self.obj.activeElement.prev().addClass('active').next().removeClass('active');
            }
        }
    });
    this.obj.parent().on('mouseenter mouseleave', function(e) {
        if (e.type == 'mouseenter') 
        {
            $(this).addClass('stop');
        }
        else 
        {
            $(this).removeClass('stop'); 
        }
    });
    setInterval(function() {
        if(self.obj.settings.items > 0 && !self.obj.parent().hasClass("stop"))
        {
            self.pagerNext.click();
        }
    }, this.obj.settings.autoChangeTime);

    };

并调用:

new MiniSlider("mini-slider");
4

2 回答 2

4

Alexthis在您的回调中为您提供了问题的解决方案,但您的代码中还有另一个问题。

您在miniSlider()没有运算符的情况下调用该函数new

miniSlider("mini-slider");

也就是说,函数里面,this并不是唯一的对象,而是真正的window对象!

您需要使用new运算符为每个调用创建一个单独的对象:

new miniSlider("mini-slider");

但是您还应该更改此函数的名称以遵循构造函数以大写字母开头的 JavaScript 约定。调用它MiniSlider并像这样使用它:

new MiniSlider("mini-slider");

如果您遵循这个约定(大多数有经验的 JavaScript 程序员都会这样做),它将帮助您记住何时使用new. 如果函数以大写字母开头,则它是一个构造函数,您需要new与它一起使用。否则,你不会。

如果您希望能够在没有 new的情况下使用构造函数,也可以使用更多代码,例如:

function MiniSlider( objId ) {
    if( this == window ) return new MiniSlider( objId );
    // the rest of your constructor code goes here
}

但通常人们不会为此烦恼,只是使用构造函数上的首字母大写来提醒使用new.

另外,作为建议,我喜欢在保存this变量时使用有意义的名称,然后我始终使用该名称而不是this根本使用该名称。这样做可能看起来像:

var miniSlider = function(objId) {
    var slider = this;

    slider.obj = $("#" + objId);
    slider.obj.settings = [];
    slider.obj.settings['items'] = $('ul li', slider.obj).length;

    slider.pagerNext = slider.obj.find("i.next");
    slider.pagerPrev = slider.obj.find("i.prev");
    slider.pagerNext.on("click", function() {
        alert(slider.obj.settings['items']);
    });
};

为什么我更喜欢这种方法而不是this在大多数地方使用另一个变量,比如self你需要它的地方?这样我就不必记住要使用哪个:我总是可以slider在代码中使用而不是this. (当然你可以使用self或任何其他名称;如果我要费心编一个名字,我只是想取一个更有意义的名字。)

代码中的另一个小问题是在这两个语句中:

    slider.obj.settings = [];
    slider.obj.settings['items'] = $('ul li', slider.obj).length;

Array当你要给它这样的命名属性时,你不应该使用它。改用一个Object。仅当您具有 0、1、2 等数字索引时才应使用数组。并且使用对象文字,您可以同时设置属性:

    slider.obj.settings = {
        items: $('ul li', slider.obj).length
    };

此外,当您使用该属性时:

        alert(slider.obj.settings['items']);

你可以更简单地写成:

        alert(slider.obj.settings.items);

无论哪种方式,它都会做同样的事情。

于 2013-07-04T20:28:13.327 回答
2

将对此的引用保存在局部变量中,并使用该变量而不是this嵌套函数。

var self = this;
this.pagerNext.on("click", function() {
  alert(self.obj.settings['items']);
});
于 2013-07-04T20:25:50.860 回答