This project is just for my own satisfaction, so I’m not really looking for other libraries to accomplish this. I’m trying to make an HTML element library:
var ElementLibrary = function() {};
(function() {
var _concatArray = [,'Element'];
var _varArray = [
'html',
'head', 'title', 'base', 'link', 'meta', 'style',
'script',
'body', 'section', 'nav', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'header', 'footer', 'address', 'main',
'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure', 'figcaption', 'div',
'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr',
'ins', 'del',
'img', 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source', 'track', 'canvas', 'map', 'area', 'svg', 'math',
'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
'form', 'fieldset', 'legend', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea', 'keygen', 'output', 'progress', 'meter',
'details', 'summary', 'command', 'menu'
];
var _l = _varArray.length;
for (var i = 0; i < _l; i++) {
_concatArray[0] = _varArray[i];
ElementLibrary.prototype[_concatArray.join('')] = document.createElement(_varArray[i]);
ElementLibrary.prototype[_varArray[i]] = function() {
return this[_concatArray.join('')].cloneNode(false);
};
}
})();
The way I had originally begun to write it would have ended up at over 400 lines, so I wanted to do it in a more compact way. The good news, it partially works. If I do:
var el = new ElementLibrary();
el.pElement // <---that is correctly a paragraph element
However, that’s not really the intended use. I want to get a shallow clone off of the single prototypal property like:
var el = new ElementLibrary();
el.p() // <---this is where I run into trouble
If I call any of my ElementLibrary functions, it ONLY returns the last element in my array (menu in this case). Why does every function return only the last element when the properties are all declared properly?
EDIT: I added a fiddle and pulled the _concatArray business out.
Solution:
var ElementLibrary = function() {};
(function() {
var _varArray = [
'html',
'head', 'title', 'base', 'link', 'meta', 'style',
'script',
'body', 'section', 'nav', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'header', 'footer', 'address', 'main',
'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure', 'figcaption', 'div',
'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr',
'ins', 'del',
'img', 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source', 'track', 'canvas', 'map', 'area', 'svg', 'math',
'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
'form', 'fieldset', 'legend', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea', 'keygen', 'output', 'progress', 'meter',
'details', 'summary', 'command', 'menu'
];
var _l = _varArray.length;
for (var i = 0; i < _l; i++) {
var _temp = _varArray[i];
var _tempElement = _temp + 'Element';
(function(t, te) {
ElementLibrary.prototype[te] = document.createElement(t);
ElementLibrary.prototype[t] = function() {
return this[te].cloneNode(false);
};
})(_temp, _tempElement);
}
})();
var el = new ElementLibrary();
alert(el.p());
The functions you create in that loop do not refer to “frozen” versions of “_concatArray”. They all share a reference to the very same array.
Wrap them in another function: