document.querySelectorAll 没有从生成的 html 元素获得调用



每当用户单击按钮时,我都会显示从.html函数生成的div元素列表。代码如下

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元素生成后的createFilterBubblesTemplate函数

<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>

但是当我试图用class="icon-xmark"在span上附加click eventlistener时,它似乎不起作用。需要帮助来解决这个问题

document.querySelectorAll('.icon-xmark').forEach(item => {
item.addEventListener('click', (event) => {
console.log(event)
})
})

也许您在将元素添加到DOM之前附加了事件。尝试委派事件

document.addEventListener('click', (event) => {
const target = event.target;
if (target.classList.contains('icon-xmark')) {
console.log(event);
}
});
但是最好使用日期属性
<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);
}
});

使用Arm144的答案解决了这个问题。将onclick属性附加到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);
}

指定的单击处理程序的跨度为空,因此它们以0宽度呈现,并且您不能单击它们。

下面通过添加内容(非换行空格)来纠正这个错误。

<!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}">&nbsp;&nbsp;&nbsp;&nbsp;</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>

用jQuery方法.on()委托点击事件。将单击事件绑定到静态元素(自页面加载以来一直存在的元素,如#filtered-items),然后将单击事件委托给用户单击的.icon-xmark($(this))。这种间接的事件处理方式称为事件委托。这是必要的,因为您不能将事件处理程序绑定到动态添加的元素。

详细信息在示例中被注释

const obj = [{
"id": "1",
"section": "delivery",
"label": "Self-Pick up"
}, {
"id": "2",
"section": "delivery",
"label": "Delivery"
}]
/*
A proper arrow function should begin with a const or let
`.html()` method is like `.innerHTML` in that it it's destructive
Use `.append()`
*/
const createFilterBubblesTemplate = (obj) => {
obj.forEach(e => {
let html =`<div class="filter-btn">
<span>${e.label}</span>
<span class="icon-xmark" data-filter-id="${e.id}" data-filter-section="${e.section}"></span>
</div>`;
$("#filtered-items").append(html);
});
}
/*
Delegate click events to each ".icon-xmark" by binding the click event to
the parent tag "#filtered-items"
Note the second parameter ".icon-xmark" -- that designates "this" as ".icon-xmark"
console.log(event) does nothing
*/
$("#filtered-items").on('click', ".icon-xmark", function(e) {
const x = $(this).data('filter-id');
console.log(x);
});
createFilterBubblesTemplate(obj);
.icon-xmark {
display: inline-block;
padding: 5px;
outline: 1px red dashed
}
<div class="filter-items" id="filtered-items"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

最新更新