前端新手求助:实现跨页面游戏商城添加购物车功能
问题:游戏商城购物车添加功能报错及实现方案求助
我正在参与前端学习课程的作业,任务是完善游戏商城的购物车功能。之前只用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(); }
其他错误修正
- sessionStorage方法名:所有
getitem/setitem/removeitem改为getItem/setItem/removeItem(大小写敏感) - 变量名错误:
vartArray改为cartArray - 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)}`; }
简洁实现优化建议
- 用模板字符串渲染产品列表:替换繁琐的字符串拼接,避免语法错误:
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> `; }
- 购物车数据去重:重复添加同款游戏时累加数量,而非新增条目:
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(); }
- 页面加载自动渲染购物车:在购物车页JS末尾添加,打开页面直接显示已选商品:
window.addEventListener('DOMContentLoaded', showCartTable);
内容的提问来源于stack exchange,提问作者pb-sandwich
相关产品推荐
相关产品推荐

