检查传递的元素是否已经初始化 return 它的实例 javascript 插件

Check if passed element is already initialized return its instance javascript plugin

插件代码:

( function() {
    this.Modal = function modal( selector, options ) {
        // If there's a passed element is already initialized return its instance
        if ( !modal.instances ) {
            modal.instances = {};
        }
        if ( modal.instances[ selector ] ) {
            return modal.instances[ selector ];
        }
        modal.instances[ selector ] = this;

        // Plugin options
        var defaults = {
            open: false
        };
        this.options = extendDefaults( defaults, options );
        selector.style.setProperty( 'background-color', 'red' );
    }

    function extendDefaults( source, properties ) {
        var property;
        for ( property in properties ) {
            if ( properties.hasOwnProperty( property ) ) {
                source[ property ] = properties[ property ];
            }
        }
        return source;
    }
}() );

到 运行 插件:

$( window ).on( 'load', function() {
    $( '.button' ).each( function() {
        var myPlugin = new Modal( this );
    } );
} );

HTML代码:

<button class="button">First Button</button>
<button class="button">Second Button</button>
<button class="button">Third Button</button>

代码错误,第一个按钮只会读取插件并获得红色背景,第二个和第三个按钮将 return 第一个按钮的实例,我不明白这是为什么碰巧按钮具有相同的 class,是的,但有不同的元素。

我需要从插件调用的每个按钮都获得红色背景颜色,同时避免多次初始化(如果传递的元素已经初始化 return 它的实例)。

好的。问题出在此处的对象方法中,因为对象的键只能是字符串。当我们尝试像这样 modal.instances[ selector ] = this; 时,我们实际上将对任何 html 按钮元素使用此 modal.instances['[object HTMLButtonElement]'] = this;。所以解决方案是使用 Map 方法,因为地图的键可以是对象。

(function() {
  const modalInstances = new Map();

  this.Modal = function(element, options) {
    if (modalInstances.has(element)) {
      console.log('return instance for: ' + element.innerHTML);
      return modalInstances.get(element);
    }

    modalInstances.set(element, this);

    // Plugin options
    var defaults = {
      open: false
    };
    this.options = extendDefaults(defaults, options);
    element.style.setProperty('background-color', 'red');
  }

  function extendDefaults(source, properties) {
    var property;
    for (property in properties) {
      if (properties.hasOwnProperty(property)) {
        source[property] = properties[property];
      }
    }
    return source;
  }
}());

$(window).on('load', function() {
  $('.button').each(function() {
    var myPlugin = new Modal(this);
  });
  
  // we will use already careated instances here, see the console.log
  $('.button').each(function() {
    var myPlugin = new Modal(this);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="button">First Button</button>
<button class="button">Second Button</button>
<button class="button">Third Button</button>