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

将HTML移入JavaScript后,卡片滑块及增减按钮失效求助

卡片滑块按钮失效问题排查与修复

核心问题:Wrapper内容被完全覆盖

你的shop变量指向#wrapper元素,执行shop.innerHTML = ...会直接替换掉wrapper内原本的<ul class="carousel">和左右按钮组,导致滑块按钮被删除,自然无法工作。

修复方法:
将卡片插入到carousel元素中,而非替换整个wrapper的内容:

let generateShop = () => {
  return (carousel.innerHTML = shopItemsData
    .map((x) => {
      // 原模板字符串内容保持不变
    })
    .join(""));
};

滑块左右按钮失效修复

原代码中,firstImg = carousel.querySelectorAll(".card")[0]在generateShop()之前执行,此时carousel内还未生成卡片,firstImg为undefined,点击按钮时访问firstImg.clientWidth会直接报错。

修复方法:
在点击事件内部动态获取第一个卡片,避免依赖初始状态,同时修正- -20的冗余写法:

arrowIcons.forEach((icon) => {
  icon.addEventListener("click", () => {
    const firstImg = carousel.querySelector(".card");
    if (!firstImg) return; // 无卡片时停止执行
    let firstImgWidth = firstImg.clientWidth + 20;
    carousel.scrollLeft += icon.id === "left" ? -firstImgWidth : firstImgWidth;
  });
});

增减按钮失效修复

问题根源

  1. 若JS代码以模块方式引入(type="module"),let声明的increment/decrement不会挂载到全局window对象,模板中的onclick="increment()"无法找到函数。
  2. 即使函数可访问,也无法区分点击的是哪个商品的按钮。

修复方案(推荐事件委托):
去掉模板中的内联onclick,通过事件委托统一监听按钮点击,更高效且避免全局函数问题:

  1. 修改模板字符串,为增减按钮添加标识类和商品ID属性:
return `
  <li class="card" id=product-id-${id}>
      <!-- 其他内容保持不变 -->
      <div class="price-quantity">
          <p class="description">${price} AED</p>
          <button class="btn">
              <span class="material-symbols-outlined increment-btn" data-id="${id}">add</span>
              <div id=${id} class="quantity">0</div>
              <span class="material-symbols-outlined decrement-btn" data-id="${id}">remove</span>
          </button>
      </div>
  </li>
`;
  1. 在generateShop()之后添加事件委托逻辑:
document.addEventListener("click", (e) => {
  const target = e.target;
  const productId = target.dataset.id;
  if (!productId) return;

  const quantityEl = document.getElementById(productId);
  let currentQty = parseInt(quantityEl.textContent);

  if (target.classList.contains("increment-btn")) {
    quantityEl.textContent = currentQty + 1;
    console.log(`Incremented product ${productId}`);
  } else if (target.classList.contains("decrement-btn")) {
    if (currentQty > 0) { // 避免数量为负
      quantityEl.textContent = currentQty - 1;
      console.log(`Decremented product ${productId}`);
    }
  }
});

完整修复后JS代码示例

const carousel = document.querySelector(".carousel"),
  arrowIcons = document.querySelectorAll(".wrapper .fa");

// 滑块按钮事件监听
arrowIcons.forEach((icon) => {
  icon.addEventListener("click", () => {
    const firstImg = carousel.querySelector(".card");
    if (!firstImg) return;
    let firstImgWidth = firstImg.clientWidth + 20;
    carousel.scrollLeft += icon.id === "left" ? -firstImgWidth : firstImgWidth;
  });
});

let shopItemsData = [
  {
    id: "one",
    name: "Banana",
    price: 3.5,
    desc: "Ecuador",
    img: "download (6).png",
  },
  {
    id: "two",
    name: "Organic Loaf",
    price: 5,
    desc: "UAE",
    img: "downloadd.png",
  },
  {
    id: "three",
    name: "Pumpkin",
    price: 6.3,
    desc: "USA",
    img: "download (3).png",
  },
  {
    id: "four",
    name: "Strawberry",
    price: 10,
    desc: "Egypt",
    img: "download (4).png",
  },
  {
    id: "five",
    name: "Papaya",
    price: 8,
    desc: "Kenya",
    img: "download (2).png",
  },
  {
    id: "six",
    name: "Orange",
    price: 3.75,
    desc: "Spain",
    img: "download (5).png",
  },
];

let generateShop = () => {
  return (carousel.innerHTML = shopItemsData
    .map((x) => {
      let { id, name, price, desc, img } = x;
      return `
        <li class="card" id=product-id-${id}>
            <img src="${img}" alt="" class="card-img">
                <div class="details">
                    <h2>${name}</h2>
                    <p>${desc}</p>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit, Ipsum, dicta!</p>
                </div>
                <div class="price-quantity">
                    <p class="description">${price} AED</p>
                    <button class="btn">
                        <span class="material-symbols-outlined increment-btn" data-id="${id}">add</span>
                        <div id=${id} class="quantity">0</div>
                        <span class="material-symbols-outlined decrement-btn" data-id="${id}">remove</span>
                    </button>
                </div>
        </li>
               `;
    })
    .join(""));
};

generateShop();

// 增减按钮事件委托
document.addEventListener("click", (e) => {
  const target = e.target;
  const productId = target.dataset.id;
  if (!productId) return;

  const quantityEl = document.getElementById(productId);
  let currentQty = parseInt(quantityEl.textContent);

  if (target.classList.contains("increment-btn")) {
    quantityEl.textContent = currentQty + 1;
    console.log(`Incremented product ${productId}`);
  } else if (target.classList.contains("decrement-btn")) {
    if (currentQty > 0) {
      quantityEl.textContent = currentQty - 1;
      console.log(`Decremented product ${productId}`);
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:30:06