создание элемента со слушателем
function CE(element, attribute, inner) {
if (typeof element === 'undefined') return false
if (typeof inner === 'undefined') inner = ''
const el = document.createElement(element)
if (typeof attribute === 'object') {
for (const key in attribute) {
const attr = attribute[key]
if (Object.prototype.toString.call(attr).includes('Object')) {
const entries = Object.entries(attr)
switch (key) {
case 'data':
entries.map(([k, v]) => (el.dataset[k] = v))
break
case 'style':
entries.map(([k, v]) => (el.style[k] = v))
break
}
} else {
if (key === 'checked' && attr === false) continue
el.setAttribute(key, attr)
}
}
}
if (!Array.isArray(inner)) inner = [inner]
for (const key of inner) {
if (key?.tagName) el.appendChild(key)
else if (key?.startsWith('<')) el.innerHTML = key
else el.appendChild(document.createTextNode(key))
}
return el
}
// так всё работает
const menu = CE('div', { class: 'menu' }, [
CE('div', { }, 'open'),
CE('div', { }, 'copy'),
CE('div', { data: { key: 'close' } }, 'close'),
CE('div', { data: { key: 'open' } }, 'open')
])
document.body.append(menu)
дело в том что мне бы хотелось после создания элемента добавить слушателя типа:
// а так к сожалению ничего не работает
const menu = CE('div', { class: 'menu' }, [
CE('div', { }, 'open').addEventListener('click', e => console.log(e), false),
CE('div', { }, 'copy').addEventListener('click', e => console.log(e), false),
CE('div', { data: { key: 'close' } }, 'close').addEventListener('click', e => console.log(e), false),
CE('div', { data: { key: 'open' } }, 'open').addEventListener('click', e => console.log(e), false)
])
но после добавления слушателя всё ломается...
P.S. использование jQuery не вариант, а вот метод как там, хотелось бы.
пример: $('<div>',{text: 'title'}).on('click', e => console.log(e))
Ответы (2 шт):
Автор решения: Александр Сычёв
→ Ссылка
а что вам мешает, при создании в атрибуте передавать onclick: 'lol1()', например так сделать?
function CE(element, attribute, inner) {
if (typeof element === 'undefined') return false
if (typeof inner === 'undefined') inner = ''
const el = document.createElement(element)
if (typeof attribute === 'object') {
for (const key in attribute) {
const attr = attribute[key]
if (Object.prototype.toString.call(attr).includes('Object')) {
const entries = Object.entries(attr)
switch (key) {
case 'data':
entries.map(([k, v]) => (el.dataset[k] = v))
break
case 'style':
entries.map(([k, v]) => (el.style[k] = v))
break
}
} else {
if (key === 'checked' && attr === false) continue
el.setAttribute(key, attr)
}
}
}
if (!Array.isArray(inner)) inner = [inner]
for (const key of inner) {
if (key?.tagName) el.appendChild(key)
else if (key?.startsWith('<')) el.innerHTML = key
else el.appendChild(document.createTextNode(key))
}
return el
}
// так всё работает
const menu = CE('div', { class: 'menu' }, [
CE('div', {onclick: 'lol1()' }, 'open'),
CE('div', {onclick: 'lol2()' }, 'copy'),
CE('div', { data: { key: 'close' }, onclick: 'lol3()' }, 'close'),
CE('div', { data: { key: 'open' }, onclick: 'lol4()' }, 'open')
])
document.querySelector('.out').append(menu)
function lol1(){
console.log('work1')
}
function lol2(){
console.log('work2')
}
function lol3(){
console.log('work3')
}
function lol4(){
console.log('work4')
}
<div class="out"></div>
Автор решения: Виталий Шебаниц
→ Ссылка
Как добавить еще один параметр вам уже написали. Опубликую ответ как бы я переделал вашу функцию. Я опустил ваши различные условия и пытался перенести смысл. Почему лучше...в основном потому что расширять такую структуру легче.
class Builder{
constructor(id){
this.container = document.getElementById(id);
}
addItem(tag){
return new MenuItem(tag, null, this)
}
render(element){
this.container.append(element);
}
}
class MenuItem {
constructor(tag, parent = null, builder = null){
this.tag = tag;
this.parent = parent;
this.builder = builder;
this.element = document.createElement(tag);
}
addAttribute(attr,value){
this.element.setAttribute(attr, value);
return this;
}
addInnerItem(tag){
return new MenuItem(tag, this)
}
addText(text){
this.element.textContent = text;
return this;
}
execute(){
this.parent.element.append(this.element)
return this.parent;
}
addEvent(type, fn){
this.element.addEventListener(type, fn);
return this;
}
build(){
this.builder.render(this.element)
}
static isMenuItem(object){
return object.itemName != undefined && object.attributes != undefined && object.innerElements != undefined;
}
}
new Builder('container')
.addItem('div')
.addAttribute('class','menu')
.addInnerItem('div')
.addText('open')
.addEvent('click', () => {
alert('open')
})
.execute()
.addInnerItem('div')
.addText('insert')
.addEvent('click', () => {
alert('insert')
})
.execute()
.build()
<div id="container">
</div>