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

落爺英雄遲暮 提交于 2020-06-29 03:39:07

问题


Plugin code:

( 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;
    }
}() );

To run the plugin:

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

HTML Code:

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

The wrong on the code that the first button only will read the plugin and gets the red background and the second and third buttons will return the instance of the first button, And I don't why this happens the buttons has the same class, yes but there are different elements.

I need every button called from the plugin gets the red background color and at the same time avoid initialized multiple times (If the passed element is already initialized return its instance).


回答1:


Ok. The problem is in objects approach here because the keys of the object can be only strings. And when we are trying to so smth like this modal.instances[ selector ] = this; we actually will have this modal.instances['[object HTMLButtonElement]'] = this; for any of the html button element. So the solution is to use Map approach, because the keys of the map can be an objects.

(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>


来源:https://stackoverflow.com/questions/62229248/check-if-passed-element-is-already-initialized-return-its-instance-javascript-pl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!