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

前端新手求助:实现跨页面游戏商城添加购物车功能

问题:游戏商城购物车添加功能报错及实现方案求助

我正在参与前端学习课程的作业,任务是完善游戏商城的购物车功能。之前只用HTML和CSS做了页面设计,刚接触JavaScript。已经成功把游戏数组渲染成产品页面,产品页和购物车页是独立页面,想实现点击“Add”按钮把游戏加入购物车,但尝试的代码出现gameProduct.find is not a function错误,求解决方法或者更简洁的实现方案。

相关代码

产品页HTML

<main>
    <h1>Game list</h1>
    <div id="game-container"></div>
</main>
<script src="JS/games-cart.js"></script>

购物车页HTML

<main>
    <h1>Shopping Cart</h1>
    <div id="shopping-cart">
            <a onClick="emptyCart()">Empty Cart</a>
            <table class="checkout-table" cellpadding="15" cellspacing="1">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th width="10%">Price</th>
                        <th width="5%">Amount</th>
                        <th width="15%">Sub Total</th>
                    </tr>
                </thead>
                <tbody id="cart-tablebody">
                </tbody>
                <tfoot>
                    <tr>
                        <td>Total:</td>
                        <td id="game-count" colspan="2"></td>
                        <td id="grand-total"></td>
                    </tr>
                </tfoot>
            </table>
    </div>
</main>
<script src="JS/script.js"></script>

现有JavaScript代码(产品页渲染)

let gameContainer = document.querySelector('#game-container');
let cartContainer = document.querySelector('#cart-tablebody');

/* Arrays */

let product = [{
        title: "Assassin's Creed: Valhalla",
        price: "599,-",
        rated: "Rated: PEGI18",
        gameURL: "acv.html"
},
{
        title: "Dragon Age: Origins",
        price: "199,-",
        rated: "Rated: PEGI18",
        gameURL: "dao.html"
},
{
        title: "Resident Evil Village",
        price: "699,-",
        rated: "Rated: PEGI18",
        gameURL: "reviii.html"
}];

console.log(product);

/* Generate Product List */

for (let i = 0; i < product.length; i++) {
        gameContainer.innerHTML += '<div class="game-product">' +
                '<a href="games/' + product[i].gameURL + '" class="game-title" alt="' + product[i].title + '">' + product[i].title + '</a><br>' +
                '<p class="pricetag">$<span>' + product[i].price + '</span></p>' +
                '<p>' + product[i].rated + '</p>' +
                '<div class="cart-add">' +
                        '<label for="amount">Amount: </label>' +
                        '<select name="amount" class="game-amount">'+
                        '<option value="1">1</option>' +
                        '<option value="2">2</option>' +
                        '<option value="3">3</option>' +
                        '<option value="4">4</option>' +
                        '<option value="5">5</option>' +
                        '<input type="submit" value="Add" class="cta add-to-cart" onClick="addToCart(this)" />'+
                '</div>'
        '</div>';
};

报错的购物车功能代码

function addToCart(target) {
    var gameProduct =(target).closest('div.game-product');

    var price = (gameProduct).find('.price span').text();
    var title = (gameProduct).find('.title').text();
    var amount = (gameProduct).find('.game-amount').text();

    var cartitem = {
        title: title,
        price: price,
        amount: amount
    };
    var cartitemJSON = JSON.stringify(cartitem);

    var cartArray = new Array();
    if (sessionStorage.getitem('shopping-cart')) {
        cartArray = JSON.parse(sessionStorage.getitem('shopping-cart'));
    }
    vartArray.push(cartitemJSON);

    var cartJSON = JSON.stringify(cartArray);
    sessionStorage.setitem('shopping-cart', cartJSON);
    showCartTable();
}

function emptyCart() {
    if (sessionStorage.getitem('shopping-cart')) {
        sessionStorage.removeitem('shopping-cart');
        showCartTable();
    }
}

function showCartTable() {
    var cartRowHTML = "";
    var gameCount= 0;
    var grandTotal = 0;

    var price = 0;
    var amount = 0;
    var subTotal = 0;

    if (sessionStorage.getitem('shopping-cart')) {
        var shoppingCart = JSON.parse(sessionStorage.getitem('shopping-cart'));
        gameCount = shoppingCart.length;

        shoppingCart.forEach(function(game) {
            var cartitem = JSON.parse(game);
            price = parseFloat(cartitem.price);
            amount = parseInt(cartitem.amount);
            total = price * amount

            carRowHTML += '<tr>' +
            '<td><img src="products/' + product[i].photo + '" class=cover--smallest" alt="' + product[i].title + 'cover art"></td>' +
            '<td>$' + product[i].title + '</td>' +
            '<td>$' + price.toFixed(2) + '</td>' +
            '<td>$' + amount + '</td>' +
            '<td>$' + subTotal.toFixed(2) + '</td>' +
            '</tr>';

            grandTotal += subTotal;
        });
    }

    $('$cartTableBody').html(cartRowHTML);
    $('#gameCount').text(gameCount);
    $('#totalAmount').text("$" + grandTotal.toFixed(2));
}

解决方案

核心错误修复:gameProduct.find is not a function

gameProduct是原生DOM元素,不是jQuery对象,不能用jQuery的find()方法,要换成原生JS的querySelector()。同时代码里的类名、取值方式也有错误,修正后的addToCart函数:

function addToCart(target) {
    const gameProduct = target.closest('div.game-product');

    // 用原生JS获取元素内容/值,修正类名匹配错误
    const price = gameProduct.querySelector('.pricetag span').textContent.trim().replace(',-', '');
    const title = gameProduct.querySelector('.game-title').textContent.trim();
    const amount = gameProduct.querySelector('.game-amount').value;

    const cartItem = {
        title: title,
        price: price,
        amount: amount
    };

    // 修正sessionStorage方法名拼写错误,直接存储对象数组
    let cartArray = JSON.parse(sessionStorage.getItem('shopping-cart')) || [];
    cartArray.push(cartItem);
    sessionStorage.setItem('shopping-cart', JSON.stringify(cartArray));
    
    showCartTable();
}

其他错误修正

  1. sessionStorage方法名:所有getitem/setitem/removeitem改为getItem/setItem/removeItem(大小写敏感)
  2. 变量名错误:vartArray改为cartArray
  3. showCartTable函数修正:
    • 不用二次解析JSON,直接操作对象数组
    • 修正变量计算逻辑,把total赋值给subTotal
    • 购物车页无product数组,直接从sessionStorage取数据
    • 用原生JS操作DOM,替换jQuery语法
    • 修正元素ID匹配错误

修正后的emptyCart和showCartTable:

function emptyCart() {
    sessionStorage.removeItem('shopping-cart');
    showCartTable();
}

function showCartTable() {
    const cartTableBody = document.querySelector('#cart-tablebody');
    const gameCountEl = document.querySelector('#game-count');
    const grandTotalEl = document.querySelector('#grand-total');
    
    let cartRowHTML = "";
    let gameCount = 0;
    let grandTotal = 0;

    const cartArray = JSON.parse(sessionStorage.getItem('shopping-cart')) || [];
    gameCount = cartArray.length;

    cartArray.forEach(item => {
        const price = parseFloat(item.price);
        const amount = parseInt(item.amount);
        const subTotal = price * amount;
        grandTotal += subTotal;

        cartRowHTML += `
            <tr>
                <td>${item.title}</td>
                <td>$${price.toFixed(2)}</td>
                <td>${amount}</td>
                <td>$${subTotal.toFixed(2)}</td>
            </tr>
        `;
    });

    cartTableBody.innerHTML = cartRowHTML;
    gameCountEl.textContent = `共 ${gameCount} 件商品`;
    grandTotalEl.textContent = `$${grandTotal.toFixed(2)}`;
}

简洁实现优化建议

  1. 用模板字符串渲染产品列表:替换繁琐的字符串拼接,避免语法错误:
for (let i = 0; i < product.length; i++) {
    const game = product[i];
    gameContainer.innerHTML += `
        <div class="game-product">
            <a href="games/${game.gameURL}" class="game-title" alt="${game.title}">${game.title}</a><br>
            <p class="pricetag">$<span>${game.price}</span></p>
            <p>${game.rated}</p>
            <div class="cart-add">
                <label for="amount">Amount: </label>
                <select name="amount" class="game-amount">
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                </select>
                <input type="submit" value="Add" class="cta add-to-cart" onClick="addToCart(this)" />
            </div>
        </div>
    `;
}
  1. 购物车数据去重:重复添加同款游戏时累加数量,而非新增条目:
function addToCart(target) {
    // ... 前面获取title、price、amount的代码不变
    let cartArray = JSON.parse(sessionStorage.getItem('shopping-cart')) || [];
    
    const existingItemIndex = cartArray.findIndex(item => item.title === title);
    if (existingItemIndex !== -1) {
        cartArray[existingItemIndex].amount = parseInt(cartArray[existingItemIndex].amount) + parseInt(amount);
    } else {
        cartArray.push(cartItem);
    }

    sessionStorage.setItem('shopping-cart', JSON.stringify(cartArray));
    showCartTable();
}
  1. 页面加载自动渲染购物车:在购物车页JS末尾添加,打开页面直接显示已选商品:
window.addEventListener('DOMContentLoaded', showCartTable);

内容的提问来源于stack exchange,提问作者pb-sandwich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:21:14