我有一个 EJS 模板,它通过运行 for 循环被包含在页面上。每个模板都有一个链接,单击该链接会切换显示/隐藏多个复选框。我正在尝试使用 AJAX 并有一个链接到模板的 javascript 文件。在这个 javascript 文件中,我向该模板上的链接添加了一个事件监听器。但是,只有页面上第一个模板上的链接会触发。
EJS模板:
<link rel="stylesheet" href="../css/categorieslist.css">
<article class="post-item" id="<%= user.UserID %>" data-userId="<%= user.UserID %>">
<p>
<%= user.Email %>
<input type="hidden" class="hiddenField" id="userid" name="userid" value="<%= user.UserID %>" required>
<p><%= user.UserID %></p>
<a class="btn catbtn" href="/admin-usercategories/<%= user.UserID %>/edit">Edit Call</a>
<div class="categorieslist">
<% for (const cat of categories) { %>
<p>
<input type="checkbox" id="<%= cat.CategoryID %>" value="<%= cat.CategoryID %>">
<label for="<%=cat.CategoryID %>"><%= cat.CategoryName %></label>
</p>
<% } %>
</div>
</p>
</article>
<script type="text/javascript" src="/javascript/usercategories.js" charset="utf-8"></script>
javascript文件:
const btn = document.querySelector(".catbtn");
const displayElement = document.querySelector(".categorieslist");
btn.addEventListener('click', function() {
fetchUserCategories();
});
async function fetchUserCategories() {
if (displayElement.style.display === "none") {
displayElement.style.display = "block";
} else {
displayElement.style.display = "none";
}
}
但是只有页面上第一个模板上的链接会触发。
因为点击处理程序仅附加到一个元素。这找到一个元素:
const btn = document.querySelector(".catbtn");
甚至变量名也暗示了这一点。然后变量的用法表明它只是一个元素:
btn.addEventListener('click', function() {
fetchUserCategories();
});
如果你想找到多个元素,你想要
querySelectorAll
:
const btns = document.querySelectorAll(".catbtn");
然后遍历结果以附加点击处理程序:
for (let btn of btns) {
btn.addEventListener('click', function() {
fetchUserCategories();
});
}
当然,这会导致下一个问题……每个按钮做的事情完全一样。它在 first
displayElement
上“获取用户类别”。您可能想要被单击元素的直接同级元素。例如,您可以将 nextElementSibling
传递给函数:
for (let btn of btns) {
btn.addEventListener('click', function() {
fetchUserCategories(this.nextElementSibling);
});
}
然后在
fetchUserCategories
中使用该元素参考:
function fetchUserCategories(displayElement) {
// "displayElement" was passed to the function
}
如果标记可能会改变,那么您可能想尝试其他方法来获取兄弟元素。例如:
技术通常包括从当前元素 (
this
) 开始,向上遍历 DOM 到公共父元素,然后从该父元素中选择目标元素。
因为有更多的模板与具有类 catbtn 的按钮具有相同的结构。然后你可以更新这部分代码:-
const btns = document.querySelectorAll(".catbtn");
const displayElement = document.querySelector(".categorieslist");
for(let btn of btns){
btn.addEventListener('click', function() {
fetchUserCategories();
});
}