You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态创建子元素点击时无法正确获取对应标题的问题求助

问题

我有一个async函数用于生成若干元素,点击元素时想要在控制台打印该元素的标题,但使用e.target时总是返回第一个元素的标题。以下是我的HTML和JavaScript代码:

HTML代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>HomeChow</title>
    <link rel="stylesheet" href="style.css" />
    <!-- Fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap"
      rel="stylesheet"
    />

    <link
      href="https://fonts.googleapis.com/css2?family=Exo:wght@500&display=swap"
      rel="stylesheet"
    />
  </head>
  <body>
    <!-- Hero Section -->
    <div class="hero">
      <nav class="navbar">
        <div class="logo">HomeChow</div>
        <div class="menu">
          <ul>
            <li>Shop</li>
            <li>Features</li>
            <li>Recipes</li>
            <li>Hotline</li>
          </ul>
        </div>
        <div class="sigin_signup">
          <p class="login">Login</p>
          <p class="signup">SignUp</p>
        </div>
      </nav>
    </div>

    <!-- Main Content -->
    <div class="main_content">
      <!-- Search Row -->
      <div class="search_row">
        <p id="search_title">Recipe</p>
        <input
          type="text"
          class=""
          id="search_bar"
          placeholder="Search Recipes and Ingredients"
        />
        <div id="sort_by">
          <select>
            <option value="newest">Sort by: newest</option>
            <option value="oldest">Sort by: oldest</option>
          </select>
        </div>
      </div>

      <!-- Categories -->
      <div class="details_row">
        <div class="main_content_menu">
          <div class="categories">
            <div class="menu_items">
              <button class="menu_btn" id="breakfast" data-category="Breakfast">
                Breakfast
              </button>
              <button class="menu_btn" id="dessert" data-category="Dessert">
                Dessert
              </button>
              <button
                class="menu_btn"
                id="miscellaneous"
                data-category="Miscellaneous"
              >
                Miscellaneous
              </button>
              <button class="menu_btn" id="pasta" data-category="Pasta">
                Pasta
              </button>
              <button class="menu_btn" id="seafood" data-category="Seafood">
                Seafood
              </button>
              <button class="menu_btn" id="side" data-category="Side">
                Side
              </button>
              <button class="menu_btn" id="starter" data-category="Starter">
                Starter
              </button>
              <button class="menu_btn" id="vegan" data-category="Vegan">
                Vegan
              </button>
              <button
                class="menu_btn"
                id="vegetarian"
                data-category="Vegetarian"
              >
                Vegetarian
              </button>
            </div>
          </div>
        </div>

        <!-- FILTER BY CATEGORY -->

        <div class="column2">
          
        </div>
        <!--END OF  FILTER BY CATEGORY -->
      
    <div class="footer"></div>
    <script src="./app.js"></script>
  </body>
</html>

JavaScript代码

let column2 = document.querySelector(".column2");
//Other working functions here

// Selecting an option from the results -- The issue!!
  column2.addEventListener("click", (e) => {
console.log("column 2 clicked");
if (e.target.classList.contains("category_food_search_results")) {
const foodDetailsContainer = document.querySelector(
  ".category_food_details"
);
const foodTitle = foodDetailsContainer.querySelector(
  ".category_food_title"
);
console.log(foodTitle.textContent);  }});

原因分析

问题出在document.querySelector(".category_food_details")方法上——它只会返回页面中匹配该选择器的第一个元素。不管点击的是哪一个生成的元素,代码都会去取页面里第一个.category_food_details容器中的标题,自然每次打印的都是第一个元素的内容。

解决方案

要获取点击元素对应的标题,需要基于当前点击的目标元素,向上查找它所属的.category_food_details容器,再在这个容器内获取标题。可以使用Element.closest()方法实现:

let column2 = document.querySelector(".column2");

column2.addEventListener("click", (e) => {
  console.log("column 2 clicked");
  if (e.target.classList.contains("category_food_search_results")) {
    // 从点击的元素向上找最近的.category_food_details容器
    const foodDetailsContainer = e.target.closest(".category_food_details");
    if (foodDetailsContainer) { // 确保找到容器后再执行
      const foodTitle = foodDetailsContainer.querySelector(".category_food_title");
      console.log(foodTitle?.textContent); // 可选链避免找不到标题时报错
    }
  }
});

关键改动说明

  • 用e.target.closest(".category_food_details")替代document.querySelector(".category_food_details"):closest()会从当前元素开始向上遍历DOM树,找到第一个匹配选择器的祖先元素,精准定位到点击元素所属的容器。
  • 添加存在性检查:避免因DOM结构变化或元素不存在导致的报错,让代码更健壮。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:37:19