Javascript模块和范围

时间:2014-05-12 15:08:33

标签: javascript

我第一次学习Javascript模块模式,因为我的脚本开始看起来很混乱,而且我的项目越大,就越难以管理。

使用我刚刚构建的以下示例,如何才能访问我设置的'元素'?在底部函数 makeCoverBigger 中,我正在尝试使用$('.coverCar')来操作元素el.coverCar,但我无法这样做。

我没有得到任何错误,它只是不会打球。我也试过使用this.el.coverCar。我假设这是el的范围问题,或者我错过了什么?如果我将el.coverCar替换为$('.coverCar'),则可以正常使用。

<script>
var CoverCarWidget = (function() {
    var el;
    return {
        elements: {
            coverCar: $('.coverCar'),
            coverCarFilter: $('.coverCarOverlayPattern'),
            coverCarScrollBtn: $('.coverCarScroll')
        },
        init: function() {
            el = this.elements;
            this.makeCoverBigger();
        },
        makeCoverBigger: function() {
            var windowHeight = $(window).height();
            if (el.coverCar.is(':visible')) el.coverCar.height(windowHeight+'px');
            console.log("This fires okay");
        }
    };
})();

$(document).ready(function() {
    CoverCarWidget.init();
});
</script>

问题 - 现在已修复

在构建CoverCarWidget时,DOM尚未就绪,因此元素对象基本上是空的。在DOM ready / init()中设置这些元素可以解决这个问题。有关详细信息,请参阅接受的答案。

5 个答案:

答案 0 :(得分:3)

问题是,你的CoverCarWidget.elements变量只是一个普通的对象,它在创建CoverCarWidget时被初始化。这意味着在文档就绪事件触发之前会分配coverCar

当你使elements成为一个函数时,里面的jQuery选择器将在文档就绪时执行并找到元素。

var CoverCarWidget = (function() {
    var el;
    return {
        getElements: function () {
            return {
                coverCar: $('.coverCar'),
                coverCarFilter: $('.coverCarOverlayPattern'),
                coverCarScrollBtn: $('.coverCarScroll')
            };
        },
        init: function() {
            el = this.getElements();
            this.makeCoverBigger();
        },
        makeCoverBigger: function() {
            var windowHeight = $(window).height();
            if (el.coverCar.is(':visible')) el.coverCar.height(windowHeight+'px');
            console.log("This fires okay");
        }
    };
})();

$(document).ready(function() {
    CoverCarWidget.init();
});
  • 当你的代码在JSFiddle之前工作时,只是因为JSFiddle默认在页面的onLoad事件中执行你的整个JavaScript代码。
  • 顺便说一句:你的代码没有产生错误,因为如果没有元素与你的选择器匹配,jQuery总是会返回一个正确的对象并默默地做任何事情。

答案 1 :(得分:1)

使用时

var wrapper = (function() {
    var private;
    return object;
})();

wrapper成为返回的对象。

在您的情况下,要访问elements,您可以使用CoverCarWidget.elements,因为elements是返回对象的属性,已分配给CoverCarWidget

答案 2 :(得分:1)

您不需要var el;,一切都已经可以使用了。

var CoverCarWidget = (function() {
    return {
        elements: {},
        init: function() {
            this.elements = {
                coverCar: $('.coverCar'),
                coverCarFilter: $('.coverCarOverlayPattern'),
                coverCarScrollBtn: $('.coverCarScroll')
            };
            this.makeCoverBigger();
        },
        makeCoverBigger: function() {
            var windowHeight = $(window).height();
            if (this.elements.coverCar.is(':visible')) this.elements.coverCar.height(windowHeight+'px');
            console.log("This fires okay");
        }
    };
})();

$(document).ready(function() {
    CoverCarWidget.init();
});

http://jsfiddle.net/Jb5mt/2/

您也不需要init方法。

答案 3 :(得分:0)

看起来你正试图使用​​揭示模块模式,但也许我错了。使用揭示模块模式,您的代码将如下所示:

<script>
var CoverCarWidget = (function() {
    var elements: {
        coverCar: $('.coverCar'),
        coverCarFilter: $('.coverCarOverlayPattern'),
        coverCarScrollBtn: $('.coverCarScroll')
    };

    function makeCoverBigger(){
        var windowHeight = $(window).height();
        if (elements.coverCar.is(':visible')) elements.coverCar.height(windowHeight+'px');
            console.log("This fires okay");
    }

    // here you return object literal with the methods that you want to expose.
    return {
        elements: elements,
        init: function() {
            makeCoverBigger();
        },
        makeCoverBigger: makeCoverBigger
    };
})();

$(document).ready(function() {
    CoverCarWidget.init();
});
</script>

答案 4 :(得分:0)

您需要对父对象的引用。典型的惯例是使用var self = this;

var CoverCarWidget = (function() {
        var el;
        var self = this;
        return {
            elements: {
                coverCar: $('.coverCar'),
                coverCarFilter: $('.coverCarOverlayPattern'),
                coverCarScrollBtn: $('.coverCarScroll')
            },
            init: function() {
                el = self.elements;
                this.makeCoverBigger();
            },
            makeCoverBigger: function() {
                var windowHeight = $(window).height();
                if (el.coverCar.is(':visible')) el.coverCar.height(windowHeight+'px');
                console.log("This fires okay");
            }
        };
    })();

    $(document).ready(function() {
        CoverCarWidget.init();
    });