JavaScript 中的动态内容渲染问题 - 变量未正确更新

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

我在开发涉及使用 JavaScript 进行动态内容渲染的网站实现时遇到了这个问题。问题是变量未按预期更新,导致意外行为。

尽管我进行了尝试,但当单击相应的“增量”按钮时只需更新单个商品的数量时,所有商品的数量都会同时修改。

我创建了一个数组 itemsData 来存储项目数据,并定义了函数 renderItems 和incrementQuantity 来处理渲染和更新数量。我使用 itemName 变量来确定应增加哪个项目的数量。

我期望当我点击特定商品的“增量”按钮时,只有该商品的数量会增加,并且网页会反映更新的数量。然而,问题是,当我单击一件商品的“增量”按钮时,所有商品的数量都会更新,这不是预期的行为。

这是 JS 和 html:

const itemsData = [
    { name: "Item A", quantity: 0 },
    { name: "Item B", quantity: 0 },
    { name: "Item C", quantity: 0 }
];

function renderItems() {
  const container = document.getElementById("item-container");
  container.innerHTML = "";

  itemsData.forEach(item => {
    const itemDiv = document.createElement("div");
    itemDiv.innerHTML = `
            <p>${item.name}</p>
            <p>Quantity: ${item.quantity}</p>
            <button onclick="incrementQuantity('${item.name}')">Increment</button>
        `;
    container.appendChild(itemDiv);
  });
}

function incrementQuantity(itemName) {
  const itemIndex = itemsData.findIndex(item => item.name === itemName);
  if (itemIndex !== -1) {
    itemsData[itemIndex].quantity++;
    renderItems();
  }
}

renderItems();
<div id="item-container">
  <!-- Items will be dynamically added here -->
</div>
<script src="axaf_script.js"></script>

javascript event-listener dynamic-content
1个回答
0
投票

内联事件处理程序是垃圾,所以不要使用:

<button onclick="lame()">LAME</button>

请参阅事件事件委托以了解正确的事件处理。

示例中已注释详细信息

// Reference container element.
const menu = document.querySelector("menu");
// Define object array of data.
const data = [
  { name: "Item A", quantity: 0 },
  { name: "Item B", quantity: 0 },
  { name: "Item C", quantity: 0 }
];

/**
 * Add <li> to a given element (main). The number of <li> and
 * their content is determined by the given object array (array).
 * Each <li> will be the following:
 *   <li>
 *     Item * <output value="0">0</output>
 *     <button class="sub">-</button>
 *     <button class="add">+</button>
 *   </li>
 * @param {Object<DOM>} main - Element that'll contain
 *        the <li>.
 * @param {array} array - Object array that contains the
 *        content of each <li>.
 */
function renderItems(main, array) {
  array.forEach(item => {
    const listItem = document.createElement("li");
    listItem.innerHTML = `
      ${item.name} Quantity: <output value="${item.quantity}">0</output> <button class="sub">-</button><button class="add">+</button>`;
    main.append(listItem);
  });
}

// Event handler passes (event) Object by default.
function itemQuantity(event) {
  // Reference the element the user clicked.
  const clicked = event.target;
  // Reference the element that contains the clicked element.
  const li = clicked.parentElement;
  
  /*
  If clicked element is a <button> AND clicked element ISN'T
  the element registered to the "click" event (main)...
  */
  if (clicked.matches("button") && clicked != event.currentTarget) {
    // Reference the <output> in parent (li).
    let output = li.querySelector("output");
    // Convert the .value of <output> into a real number.
    let qty = Number(output.value);
    
    // If clicked element has class "add"...
    if (clicked.matches(".add")) {
      // ...increase (qty) by 1...
      qty++;
    // ...otherwise...
    } else {
      // ...decrease (qty) by 1...
      qty--;
      // ...if (qty) is less than 0...
      if (qty < 0) {
        // ...reset (qty) to 0.
        qty = 0;
      }
    }
    // Change <output> to (qty).
    output.value = qty;
  }
}

/*
Register (<menu> to the "click" event. When "click" event is
fired, call event handler itemQuantity(event).
*/
menu.onclick = itemQuantity;

renderItems(menu, data);
<menu></menu>

© www.soinside.com 2019 - 2024. All rights reserved.