检查传递的元素是否已经初始化 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>
插件代码:
( 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>