JavaScript模块模式document.ready无法正常工作

时间:2015-08-11 21:11:50

标签: javascript jquery design-patterns module

我有一个模块模式的基本示例,它只是在页面上的页脚元素中添加一个类。

  1. 当脚本加载到body标签中(在页脚元素之后)时,它会工作并将类添加到页脚。

  2. 当脚本加载到head标签(在页脚元素之前)时,即使在文档准备就绪之前不应该调用init,它也不起作用。

  3. 我认为document.ready没有按预期工作,因此它找不到页脚元素,因为它不存在。

    这一直困扰着我多年,我似乎无法找到解决办法,有人可以就这个问题说清楚吗?

    示例:https://jsfiddle.net/5x5skoq3/

    var App = (function ($) {
        "use strict";
    
        // private alias to settings
        var s;
    
        return {
            settings: {
                footer: $("footer")
            },
    
            init: function() {
                s = this.settings;
    
                this.footer();
            },
    
            footer: function(){
                s.footer.addClass("active");
            }
        };
    })(jQuery);
    
    
    jQuery(document).ready(function() {
    
        App.init();
    
    });
    

    谢谢

2 个答案:

答案 0 :(得分:0)

过早调用$.fn.inView = function(){ var rect = this[0].getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; $(window).scroll(function() { if ($('#paginator').length) { var url = $('#load_more').attr('href'); if (url && $('#load_more').inView() && $.active == 0) { $.get(url, function(data) { $('#paginator').append('<div class="spinner"></div>'); $.getScript(url); }); } } }); 不是问题,而是过早评估init。您已经在加载模块时引用了此处的元素,而不是在初始化模块时引用该元素。

幸运的是,这很容易解决:

settings: { footer: $("footer") }

答案 1 :(得分:0)

在这种情况下,App是一个自我调用的函数。该函数执行创建返回对象及其所有属性。在函数self调用时,footer: $("footer")被调用,返回一个带有length: 0的jQuery对象,表明选择器没有返回匹配的元素或元素集。我已更新您的jsfiddle,以提醒您拨打init时找到的匹配数。

您可以通过多种方式解决此问题。我可能会修复它的方法是将settings转换为对象构造函数:

&#13;
&#13;
var App = (function ($) {
    "use strict";

    // private alias to settings
    var s;

    return {
        settings: function () {
            this.footer = $('footer');
        },

        init: function() {
            s = new this.settings();

            this.footer();
        },

        footer: function(){
            s.footer.addClass("active");
        }
    };
})(jQuery);


jQuery(document).ready(function() {

    App.init();

});
&#13;
footer.active {
  background-color: red;
  color: #fff;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  Header content
</header>

<footer>
  Footer content
</footer>
&#13;
&#13;
&#13;

使用此方法,您仍然可以将逻辑保留在init函数之外,但保持与settings返回对象的原始示例的一致性。