Как отслеживать клонированную кнопку?
У менять есть блок, который клонируется и вставляется в 2 места, но клонированный блок ни как не кликается, а помимо клика, мне нужно чтоб они вместе становились активными, как это можно сделать?
const input = document.querySelector('.input');
const button = document.querySelector('.button');
const ul = document.querySelector('.ul');
const mainUl = document.querySelector('.main-ul');
button.addEventListener('click', () => {
const div = document.createElement('div');
div.classList.add('wrap')
div.innerHTML =
`
<button class="btn"></button>
<p></p>
`
const btn = div.querySelector('.btn')
const p = div.querySelector('p')
p.textContent = input.value;
ul.appendChild(div)
const cloneDiv = div.cloneNode(true)
mainUl.appendChild(cloneDiv)
btn.addEventListener('click', () => {
btn.classList.toggle('btn--active')
})
})
.wrap {
min-width: 400px;
min-height: 100px;
border: 1px solid #000;
display: flex;
justify-content: center;
align-items: center;
}
p {
max-width: 200px;
}
.btn {
width: 40px;
height: 40px;
border: 2px solid #4DD599;
background: transparent;
border-radius: 50%;
margin-right: 20px;
cursor: pointer;
}
.btn--active {
background: red;
}
<ul class="main-ul">
<h1>Main</h1>
</ul>
<ul class="ul">
<h2>Ul</h2>
</ul>
<div class="wrapper">
<input class="input" type="text">
<button class="button">Создать</button>
</div>
Ответы (2 шт):
Задействуйте делегирование. И вместо innerHTML, рекомендую использовать insertAdjacentHTML, а также, вставляйте переменные непосредственно в шаблонные литералы.
Можете добавлять сколько угодно списков - в каждый из них добавится необходимая разметка и логика будет отрабатывать, как задумано. При этом в скрипте ничего менять на потребуется.
const input = document.querySelector('.input');
const button = document.querySelector('.button');
const container = document.querySelector('.container');
button.addEventListener('click', () => {
const template =
`<div class="wrap">
<button class="btn" group="${input.value}"></button>
<p>${input.value}</p>
</div>`;
document.querySelectorAll('ul').forEach(el => el.insertAdjacentHTML('beforeend', template));
});
container.addEventListener('click', (ev) => {
if (!ev.target.classList.contains('btn')) return
document.querySelectorAll(`[group="${ev.target.getAttribute('group')}"].btn`).forEach(el => el.classList.toggle('btn--active'));
});
.wrap {
min-width: 400px;
min-height: 100px;
border: 1px solid #000;
display: flex;
justify-content: center;
align-items: center;
}
p { max-width: 200px; }
.btn {
width: 40px;
height: 40px;
border: 2px solid #4DD599;
background: transparent;
border-radius: 50%;
margin-right: 20px;
cursor: pointer;
}
.btn--active { background: red; }
<div class="container">
<ul class="main-ul">
<h1>Main</h1>
</ul>
<ul class="ul">
<h2>Ul</h2>
</ul>
<ul class="more-ul">
<h2>More</h2>
</ul>
<div class="wrapper">
<input class="input" type="text">
<button class="button">Создать</button>
</div>
</div>
Вот пример через делегирование событий, таким образом экономится еще и память. Для того чтобы обрабатывать элементы одновременно, вовсе не достаточно клонирования, для этой цели можно использовать дата аттрибуты по которым идентифицировать пары, в данном случае у меня просто индексирование пар от нуля.
const input = document.querySelector('.input');
const button = document.querySelector('.button');
const ul = document.querySelector('.ul');
const mainUl = document.querySelector('.main-ul');
let index = 0
function toggleClass(e) {
if (e.target.tagName.toLowerCase() === "button"){
// выбираем все кнопки с одним дата аттрибутом
const buttons = document.querySelectorAll(`[data-id='${e.target.dataset.id}']`)
// проходим по ним в цикле чтобы поменять классы
Array.from(buttons).forEach(e => e.classList.toggle('btn--active'))
}
}
ul.addEventListener('click', (e) => {
toggleClass(e)
})
mainUl.addEventListener('click', (e) => {
toggleClass(e)
})
button.addEventListener('click', () => {
const div = document.createElement('div');
div.classList.add('wrap')
div.innerHTML =`
<button data-id="${index++}" class="btn"></button>
<p></p>`
const btn = div.querySelector('.btn')
const p = div.querySelector('p')
p.textContent = input.value;
ul.appendChild(div)
const cloneDiv = div.cloneNode(true)
mainUl.appendChild(cloneDiv)
})
.wrap {
min-width: 400px;
min-height: 100px;
border: 1px solid #000;
display: flex;
justify-content: center;
align-items: center;
}
p {
max-width: 200px;
}
.btn {
width: 40px;
height: 40px;
border: 2px solid #4DD599;
background: transparent;
border-radius: 50%;
margin-right: 20px;
cursor: pointer;
}
.btn--active {
background: red;
}
<ul class="main-ul">
<h1>Main</h1>
</ul>
<ul class="ul">
<h2>Ul</h2>
</ul>
<div class="wrapper">
<input class="input" type="text">
<button class="button">Создать</button>
</div>