UNPKG

2.6 kBJavaScriptView Raw
1/**
2 * Create a DOM element from a CSS query with option to include content
3 *
4 * @author Laurent Blanes <laurent.blanes@gmail.com>
5 * @param {String} querySelector (optional) default to div
6 * @param {...*} [content] (optional) String|Number|DOMElement
7 * @return DOMElement
8 *
9 * @example
10 * - createElement(); // <div>
11 * - createElement('span#my-id.my-class.second-class'); // <span id="my-id" class="my-class second-class">
12 * - createElement('#my-id.my-class.second-class', 'text to insert', 12345); // <div id="my-id" class="my-class second-class">
13 * - const div = createElement('#my-div',
14 * 'Random text',
15 * createElement('p.paragraph', 'my text'),
16 * createElement('p.paragraph', 'my second text'),
17 * createElement('a.link[href=https://github.com/hekigan/create-element]', 'link to a site'),
18 * ); // <div id="my-id" class="my-class second-class">
19 * // Random text
20 * // <p class="paragraph">my text</p>
21 * // <p class="paragraph">my second text</p>
22 * // <a class="link" href="https://github.com/hekigan/create-element" class="paragraph">link to a site</a>
23 * // </div>
24 */
25export default function createElement (querySelector = 'div', ...content) {
26 let nodeType = querySelector.match(/^[a-z]+/i);
27 let id = querySelector.match(/#([a-z]+[a-z0-9-]*)/gi);
28 let classes = querySelector.match(/\.([a-z]+[a-z0-9-]*)/gi);
29 let attributes = querySelector.match(/\[([a-z][a-z-]+)(=['|"]?([^\]]*)['|"]?)?\]/gi);
30 let node = (nodeType) ? nodeType[0] : 'div';
31
32 if (id && id.length > 1) {
33 throw CreateElementException('only 1 ID is allowed');
34 }
35
36 const elt = document.createElement(node);
37
38 if (id) {
39 elt.id = id[0].replace('#', '');
40 }
41
42 if (classes) {
43 const attrClasses = classes.join(' ').replace(/\./g, '');
44 elt.setAttribute('class', attrClasses);
45 }
46
47 if (attributes) {
48 attributes.forEach(item => {
49 item = item.slice(0, -1).slice(1);
50 let [label, value] = item.split('=');
51 if (value) {
52 value = value.replace(/^['"](.*)['"]$/, '$1');
53 }
54 elt.setAttribute(label, value || '');
55 });
56 }
57
58 content.forEach(item => {
59 if (typeof item === 'string' || typeof item === 'number') {
60 elt.appendChild(document.createTextNode(item));
61 } else if (item.nodeType === document.ELEMENT_NODE) {
62 elt.appendChild(item);
63 }
64 });
65
66 return elt;
67}
68
69function CreateElementException (message) {
70 this.message = message;
71 this.name = 'CreateElementException';
72}