实例化JavaScript模块模式

3

我正在尝试在页面上创建多个滑块实例。每个滑块应该知道它当前正在查看哪个幻灯片。当我更新slide属性时,似乎我是在更改类而不是实例。这使我认为我在公共init()函数中没有正确实例化。我做错了什么?

var MySlider = (function() {

    'use strict';

    var animating = 0,
           slides = 0, // total slides
           slider = null,
            slide = 0, // current slide
             left = 0;

    function slideNext(e) {
        if ((slide === slides - 1) || animating) return;

        var slider = e.target.parentNode.children[0],
                 x = parseFloat(slider.style.left);

        animate(slider, "left", "px", x, x - 960, 800);
        slide++;
    }

    return {
        init: function() {
            var sliders = document.querySelectorAll('.my-slider'),
                      l = sliders.length;

            for (var i = 0; i < l; i++) {
                sliders[i] = MySlider; // I don't think this is correct.

                slider = sliders[i];

                buildSlider(slider);

            }
        }
    }

})();

我不明白这种创造方式的目的,除了增加无用的复杂性和错误来源之外。有人能启发我吗? - Virus721
1
你的“我不认为这是正确的”这句话说得很好。你正在将相同的对象附加到每个滑块上。我的倾向是反转这个过程,并使MySlider成为一个构造函数,它接受一个参数(单个滑块元素)来操作。为每个滑块元素创建一个新的MySlider。 - underrun
@underrun,你能给我展示一下怎么做吗?我的想法是,当有人使用这个模块时,他们只需在DOM加载后调用MySlider.init();一次,然后我的函数将循环遍历页面上匹配的元素,并为每个元素创建一个实例。我不希望他们手动创建实例。 - Jezen Thomas
2个回答

5
根据您的评论,我认为这更符合您的需求:
MySlider = (function () {
    Slider = function (e) {
        this.e = e;
        // other per element/per slider specific stuff
    }

    ...

    var sliders; // define this out here so we know its local to the module not init

    return {
        init: function () {

            sliders = document.querySelectorAll('.my-slider');
            var l = sliders.length;

            for (var i = 0; i < l; i++) {
                sliders[i] = new Slider(sliders[i]); //except I'd use a different array

                slider = sliders[i];

                buildSlider(slider);
        }
    }
})();

这样,您将每个元素与其自己的元素特定数据相关联,但是您有一个包含模块,您可以在其中操作模块集合。


3
似乎当我更新幻灯片属性时,我更改的是类,而不是实例。
您说得对。该代码仅在定义 MySlider 类时运行。如果您想要一个实例变量,则需要在返回的对象内部声明它,即在您的返回块中的一部分:
 var MySlider = (function(param) {
    return {
       slider: param, 

       init: function() {
            var sliders = document.querySelectorAll('.my-slider'),
                      l = sliders.length;

            for (var i = 0; i < l; i++) {
                sliders[i] = MySlider; // I don't think this is correct.

                slider = sliders[i];

                buildSlider(slider);

            }
        }
});

在这种情况下,实例化的正确方式是什么?在其他地方,我看到过类似于 var sliderOne = MySlider(); 的东西,但似乎我不能在我的 init() 函数中这样做。 - Jezen Thomas
创建一个构造函数的参数,然后在返回块中分配它。 - Peter Bratton
你没有在任何地方使用 slider 属性? - Bergi
我现在专注于slide属性。在我的slideNext(e)函数中,我正在检查和更新slide属性。 - Jezen Thomas
无论您想要将哪些变量设置为类/实例,相同的原则都是适用的。如果您愿意,可以编辑我的答案以输入正确的变量名称。 - Peter Bratton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接