AJAX 和 EJS 只有第一个按钮触发

问题描述 投票:0回答:2

我有一个 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";
    }
}

javascript ajax ejs
2个回答
0
投票

但是只有页面上第一个模板上的链接会触发。

因为点击处理程序仅附加到一个元素。这找到一个元素

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 到公共父元素,然后从该父元素中选择目标元素。


0
投票

因为有更多的模板与具有类 catbtn 的按钮具有相同的结构。然后你可以更新这部分代码:-

const btns = document.querySelectorAll(".catbtn");
const displayElement = document.querySelector(".categorieslist");

for(let btn of btns){
    btn.addEventListener('click', function() {
       fetchUserCategories();
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.