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

JavaScript如何选择多个section创建订单对象字面量

问题原因
  • querySelectorAll() 返回的是类数组结构的NodeList节点集合,不是单个DOM元素,集合本身没有querySelectorAll、innerText这类元素专属的方法和属性,直接对集合调用元素方法必然报“xxx不是函数”的错误。
  • 就算对NodeList调用querySelectorAll,拿到的依然是子节点的集合,集合本身不存在innerText属性,强行读取只能拿到null。
  • 你之前通过按钮parentNode选中单个商品区块的逻辑本身没问题,如果要一次性获取所有商品的订单信息,必须遍历所有.merch区块逐个提取字段,不能直接对集合做操作。
修正后的实现代码

原有HTML结构不需要调整,JS逻辑参考如下,已经包含数量加减、全量订单提取、sessionStorage存储能力:

// 初始化订单存储,优先读取sessionStorage里的已有订单,没有则初始化为空数组
let allOrders = JSON.parse(sessionStorage.getItem('merchOrders')) || [];

// 绑定商品数量加减按钮逻辑
document.querySelectorAll('[data-minusOrder], [data-plusOrder]').forEach(btn => {
  btn.addEventListener('click', function() {
    const quantityEl = this.parentElement.querySelector('.orderQuantity');
    let currentNum = parseInt(quantityEl.innerText);
    // 减号操作不允许数量小于0
    if (this.hasAttribute('data-minusOrder')) {
      currentNum = Math.max(0, currentNum - 1);
    } else {
      currentNum += 1;
    }
    quantityEl.innerText = currentNum;
  })
})

// 绑定下单按钮事件
const orderButtons = document.querySelectorAll(".orderButton");
orderButtons.forEach(function(button) {
  button.addEventListener("click", function() {
    // 单商品加购场景:获取当前点击按钮所属的商品区块,比parentNode容错率更高
    const currentMerch = this.closest('.merch');
    const currentItem = {
      id: currentMerch.id,
      title: currentMerch.querySelector(".title").innerText.trim(),
      price: currentMerch.querySelector(".price").innerText.trim(),
      description: currentMerch.querySelector(".description").innerText.trim(),
      quantity: parseInt(currentMerch.querySelector(".orderQuantity").innerText)
    };

    if (currentItem.quantity === 0) {
      alert('请先选择商品数量');
      return;
    }

    // 全量订单场景:遍历所有商品区块,提取所有选购数量大于0的商品
    const allMerchList = document.querySelectorAll('.merch');
    const validOrderList = Array.from(allMerchList).map(merchEl => {
      return {
        id: merchEl.id,
        title: merchEl.querySelector(".title").innerText.trim(),
        price: merchEl.querySelector(".price").innerText.trim(),
        description: merchEl.querySelector(".description").innerText.trim(),
        quantity: parseInt(merchEl.querySelector(".orderQuantity").innerText)
      }
    }).filter(item => item.quantity > 0);

    // 存入sessionStorage,后续提交服务端直接读取该字段即可
    sessionStorage.setItem('merchOrders', JSON.stringify(validOrderList));
    console.log('当前有效订单:', validOrderList);
  });
});
关键注意点
  • 找单个匹配元素用querySelector(),找一组匹配元素才用querySelectorAll();拿到NodeList集合后必须遍历内部元素,才能执行DOM属性读取、方法调用操作,不要直接对集合调用元素方法。
  • 查找按钮所属的商品区块推荐用this.closest('.merch'),比多层写parentNode容错率高,后续就算调整DOM结构、在按钮外层套容器,也不会找错父级区块。
  • 注意:sessionStorage只能存储字符串类型数据,存对象、数组类型的订单数据时,必须先用JSON.stringify()转成字符串,读取时再用JSON.parse()转回JS对象,否则会存成"[object Object]"的无效数据。
  • 读取元素文本后建议加.trim()去掉首尾多余的空格、换行,避免存储的字段带无用格式。
  • 商品数量读取到的是字符串类型,存数据前要转成Number类型,避免后续计算总价时出现字符串拼接的低级错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:42:14