【问题标题】:Chage configurable setting's object outside Revealing Module Pattern更改显示模块模式之外的可配置设置对象
【发布时间】:2015-02-07 08:11:28
【问题描述】:

我正在尝试练习不同的模块模式。下面是用于滚动功能的 IIFE 模式,可用于不同页面中的不同元素(不确定这是正确的模式)。

我的问题是 1. 如何替换 IIFE 模块外的 config = {} 选项? 2.我命名了每一个函数,不确定这是写这种代码的一种矫枉过正或建议的方式。 3. 什么是更好的模块模式?

  ;(function($, ScrollToTop, undefined) {
    'use strict';

    var clickedElem = $('[data-scroll]');
    var config = {
      scrollDistance: 500,
      speed: 300
    };

    var _scrollToTargetAnimation = function () {
      $('body').animate({
        scrollTop: $($(this).data('scroll')).offset().top
      }, config.speed);
      return false; //stop bubbling
    };

    var _showHideAnimation = function () {
        if ($(this).scrollTop() > config.scrollDistance) {
          clickedElem.fadeIn(config.speed);
        } else {
          clickedElem.fadeOut(config.speed);
        }
    };

    ScrollToTop.showHide = function() {
      if ($('.top-bar').length) return;
      $(document).scroll( _showHideAnimation );
    };

    ScrollToTop.clickBtn = function() {
      clickedElem.on('click', _scrollToTargetAnimation );
    };

    ScrollToTop.init = function (config) {
      $.extend(this.config, config);
      ScrollToTop.showHide();
      ScrollToTop.clickBtn();
    };

  })(jQuery, window.ScrollToTop = window.ScrollToTop || {});

  $(function() {
    config = {
      scrollDistance: 500,
      speed: 300
    };
    ScrollToTop.init(config);
  });

【问题讨论】:

    标签: javascript jquery module singleton iife


    【解决方案1】:

    首先,您拥有的不是模块模式。模块模式涉及从头开始创建对象并隐藏它的一些属性和方法。你的例子是一个装饰器——你传入一个对象ScrollToTop 并用其他方法装饰它。一些技术类似于模块模式的技术——使用 IIFE,使用闭包隐藏私有变量——但意图不同。我建议您阅读 this post 以了解模块模式变体之间的区别。

    据我了解,您的装饰器中有一个要修改的默认配置对象。由于您的装饰器函数使用副作用来实现其目标,因此您可以使用装饰器返回一个 configManager,您可以使用它来改变内部默认配置。

    var configManager = (function($, ScrollToTop, undefined) {
    
      var clickedElem = $('[data-scroll]');
      var defaultConfig = {
        scrollDistance: 500,
        speed: 300
      };
    
      var _scrollToTargetAnimation = function () {
        // ...
      };
    
      var _showHideAnimation = function () {
        // ...
      };
    
      ScrollToTop.showHide = function() {
        // ...
      };
    
      ScrollToTop.clickBtn = function() {
        // ...  
      };
    
      ScrollToTop.init = function (config) {
        // ...
      };
    
      return {
        setConfig: function(config){
            defaultConfig = config;
        }
      };
    })(jQuery, window.ScrollToTop = window.ScrollToTop || {});
    
    $(function() {
      config = {
        scrollDistance: 500,
        speed: 300
      };
      ScrollToTop.init(config);
    });
    
    configManager.setConfig({
      scrollDistance: 400,
      speed: 200
    });
    

    针对 OP 的问题添加:$.extend 不起作用的原因

    ScrollToTop.init = function (config) {
      $.extend(this.config, config);
    

    是因为参数 config 隐藏了闭包的配置,this.config 根本没有指向任何东西。这很容易通过重命名参数来更改,因此它不会隐藏闭包的配置

    ScrollToTop.init = function (config2) {
      $.extend(config, config2);
    

    【讨论】:

    • 感谢您的解决方案。我还有几个问题。 1. 为什么在模块外传入新配置时$.extend 不起作用?
    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2011-03-13
    • 1970-01-01
    • 2012-02-19
    • 2019-01-13
    相关资源
    最近更新 更多