I'm displaying list of div element that generated from .html function whenever users click a button. The code look like below
array
const obj = [{"id":"1","section":"delivery","label":"Self-Pick up"},{"id":"2","section":"delivery","label":"Delivery"}]
javascript
createFilterBubblesTemplate = (obj) => {
let bubbles = ''
obj.forEach(e => {
bubbles += `<div class="filter-btn">
<span>${e.label}</span>
<span class="icon-xmark" id="bubbles-close" data-filter-id="${e.id}" data-filter-section="${e.section}"></span>
</div>`
})
$("#filtered-items").html(bubbles);
}
html element after generated by createFilterBubblesTemplate function
<div class="filter-items" id="filtered-items">
<div class="filter-btn">
<span>Self-Pick up</span>
<span class="icon-xmark" id="bubbles-close" data-filter-id="1" data-filter-section="delivery"></span>
</div><div class="filter-btn">
<span>Delivery</span>
<span class="icon-xmark" id="bubbles-close" data-filter-id="2" data-filter-section="delivery"></span>
</div>
</div>
But when I tried to attach click eventlistener on span with class="icon-xmark", its seems not working. Need help to solve this issue
document.querySelectorAll('.icon-xmark').forEach(item => {
item.addEventListener('click', (event) => {
console.log(event)
})
})
maybe you are attach the event BEFORE you added the element to the DOM. Try to delegate the event
document.addEventListener('click', (event) => {
const target = event.target;
if (target.classList.contains('icon-xmark')) {
console.log(event);
}
});
but it's better to use the date attribute
<span class="icon-xmark" data-close id="bubbles-close" data-filter-id="2" data-filter-section="delivery"></span>
...
document.addEventListener('click', (event) => {
const target = event.target;
if ('close' in target.dataset) {
console.log(event);
}
});
The problem is fixed by using answer from Arm144. Attaching onclick attribute into the span
createFilterBubblesTemplate = async (obj) => {
let bubbles = ''
obj.forEach(e => {
bubbles += `<div class="filter-btn">
<span>${e.label}</span>
<span class="icon-xmark" onclick="closeFiltersBubbles(${e.id},'${e.section}')" data-filter-id="${e.id}" data-filter-section="${e.section}"></span>
</div>`
})
$("#filtered-items").html(bubbles);
}
The spans you assign the click handler to are empty, thus they are rendered with 0 width and you cannot click them.
The following corrects this by adding content (non-breaking spaces).
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="expires" content="0">
<meta http-equiv="cache-control" content="private">
<meta http-equiv="pragma" content="no-cache">
<title>SO - Bitmap (svg)</title>
<!--
-->
<style type="text/css">
body {
background-color: #eee;
}
.icon-xmark {
background-color: lime;
cursor: pointer;
}
</style>
<script>
const obj = [{"id":"1","section":"delivery","label":"Self-Pick up"},{"id":"2","section":"delivery","label":"Delivery"}];
let createFilterBubblesTemplate = (obj) => {
let bubbles = '';
obj.forEach(e => {
bubbles += `<div class="filter-btn">
<span>${e.label}</span>
<span class="icon-xmark" id="bubbles-close" data-filter-id="${e.id}" data-filter-section="${e.section}"> </span>
</div>`;
});
document.querySelector("#filtered-items").innerHTML = bubbles;
}; // createFilterBubblesTemplate
document.addEventListener('DOMContentLoaded', () => {
setTimeout ( () => {
createFilterBubblesTemplate(obj);
setTimeout ( () => {
document.querySelectorAll('.icon-xmark').forEach(item => {
item.addEventListener('click', (event) => {
console.log('Here we go...');
});
});
}
, 1000
);
}
, 1000
);
});
</script>
</head>
<body>
<div class="filter-items" id="filtered-items"></div>
</body>
</html>