繁体   English   中英

如何将产品项目添加到购物车以及如何在始终(重新)计算购物车项目的总价的同时将其从那里删除?

[英]How does one add a product-item to a shopping-cart and how would one remove it from there while always (re)calculating the cart items' total price?

以下数组具有作为产品项目的对象。 单击“ Add to cart按钮应通过mytable函数将相关项目呈现为表格演示,如下所示。

var product = [
  {"name":"jeans","image":"pics/jeans3.jpg","price":500},
  {"name":"hoodie","image":"pics/hoodie.jpg","price":700},
  {"name":"shirt","image":"pics/shirt.jpg","price":450},
  {"name":"sweter","image":"pics/sweter.jpg","price":1100},
  {"name":"trouser","image":"pics/trouser.jpg","price":600},
  {"name":"tshirt","image":"pics/tshirt.jpg","price":250}
];

这是应该从上面提供的数据创建产品概述(包括事件处理)的循环。

var head = "<div id='main'>";

for (var i in product) {
  head += "<div class='pro'>";
  head += "<h1>" + product[i].name + "</h1>";
  head += "<img src=" + product[i].image + ">";
  head += "<p>" + product[i].price + "</p>";
  head += "<button onclick='mytable(i)'>Add to cart</button>"
  head += "</div>";
}

这是上面代码的其余部分,预计将产品概述写入文档。 还有上面提到的mytable函数,它应该创建一个商品购物车展示(包括事件处理)。

head += "</div>";
head += "<div id='cart'> </div>"
document.write(head);

function mytable(i) {
     document.getElementById('cart').innerHTML = "<table border='1'> <tr><th>Product name</th>  <th>Quantity</th>  <th>Price</th> <th>image</th><th><button>Remove Items</button></th></tr></table>";
} 

另外我想处理购物车项目的删除。 对于在购物车中添加和删除商品的两种情况,我想计算所有购物车商品的总价。

怎么能做到这一点?

正在使用的技术...

网络接口

事件委托

句法

表达式和运算符

JavaScript Api / 标准内置对象的方法

 const productList = [ { pid: "abcd-0987-WXYZ", name: "jeans", price: 500, image: "https://media.istockphoto.com/photos/blue-denim-picture-id501250332" }, { pid: "efgh-1234-QRST", name: "hoodie", price: 700, image: "https://media.istockphoto.com/photos/faceless-man-in-hoodie-standing-isolated-on-black-picture-id916306960" }, { pid: "ijkl-6543-MNOP", name: "shirt", price: 450, image: "https://media.istockphoto.com/photos/men-shirt-for-clothing-isolated-on-white-background-picture-id641319368" }, { pid: "mnop-5678-IJKL", name: "sweater", price: 1100, image: "https://media.istockphoto.com/photos/minimalistic-rustic-composition-with-stacked-vintage-knitted-easy-picture-id1049751604" }, { pid: "qrst-2109-EFGH", name: "trouser", price: 600, image: "https://media.istockphoto.com/photos/pants-picture-id168790494" }, { pid: "wxyz-9012-ABCD", name: "tshirt", price: 250, image: "https://media.istockphoto.com/photos/close-up-of-colorful-tshirts-on-hangers-apparel-background-picture-id1170635789" }, ]; function createElementFromMarkup(html) { const renderBox = document.createElement('div'); renderBox.innerHTML = html; return renderBox.firstElementChild; } function createItemMainView(data) { return createElementFromMarkup(` <li data-pid="${ data.pid }"> <h3>${ data.name }</h3> <img src="${ data.image }"/> <dl><dt>Price</dt><dd>${ data.price }</dd></dl> <button data-add-pid="${ data.pid }" data-text="Add to cart">Add to cart</button> </li> `); } function createItemCartView(data) { return createElementFromMarkup(` <li data-pid="${ data.pid }"> <h3>${ data.name }</h3> <dl><dt>Price</dt><dd>${ data.price }</dd></dl> <button data-remove-pid="${ data.pid }">Remove</button> </li> `); } function createShoppingItem(data) { return { data, view: { main: createItemMainView(data), cart: createItemCartView(data), }, checkout: { isInCart: false, orderCount: 0, }, }; } function scrollIntoViewIfNeeded(elmNode) { if (elmNode) { const whichScrollIntoView = elmNode.scrollIntoViewIfNeeded ? 'scrollIntoViewIfNeeded' : 'scrollIntoView'; elmNode[whichScrollIntoView](); } } function updateShoppingCartTotal(elmCartTotal, shoppingState) { const total = Object .values(shoppingState) .reduce((sum, item) => (sum + ((item.data.price ?? 0) * (item.checkout.orderCount ?? 0))), 0 ); elmCartTotal.textContent = (total === 0) ? '' : total; } function updateCartItemPriceView(elmPrice, price, orderCount) { elmPrice.textContent = (orderCount >= 2) ? `${ price } x ${ orderCount }` : price; } function updateAddButtonItemCount(elmButton, orderCount) { const { text: buttonText } = elmButton.dataset; elmButton.textContent = (orderCount >= 1) ? `${ buttonText } (${ orderCount })` : buttonText; } function updateOrderCounts(pid, context) { const { target: { elmMainOverview, elmCartOverview, elmCartTotal }, state: shoppingState, } = context; const shoppingItem = shoppingState[pid]; const orderCount = shoppingItem?.checkout?.orderCount ?? 0; const elmButton = elmMainOverview .querySelector(`[data-add-pid="${ pid }"]`); const elmPrice = (orderCount >= 1) && elmCartOverview .querySelector(`[data-pid="${ pid }"] dd`); if (elmButton) { updateAddButtonItemCount(elmButton, orderCount); } if (elmPrice) { updateCartItemPriceView(elmPrice, shoppingItem?.data?.price, orderCount); } updateShoppingCartTotal(elmCartTotal, shoppingState); } function handleAddToCartWithBoundTargetAndState(evt) { const target = evt.target.closest('[data-add-pid]'); if (target) { const { addPid: pid } = target.dataset; const { target: { elmCartOverview }, state: shoppingState, } = this; const item = shoppingState[pid]; if (item) { if (item.checkout.isInCart === false) { elmCartOverview.appendChild(item.view.cart.cloneNode(true)); item.checkout.isInCart = true; } item.checkout.orderCount += 1; scrollIntoViewIfNeeded( elmCartOverview.querySelector(`[data-pid="${ pid }"]`) ); updateOrderCounts(pid, this); } // console.log('Add To Cart :: pid ...', pid); } console.log('Add To Cart :: evt.target ...', evt.target); } function handleRemoveFromCartWithBoundTargetAndState(evt) { const target = evt.target.closest('[data-remove-pid]'); if (target) { const { removePid: pid } = target.dataset; const { target: { elmMainOverview, elmCartOverview }, state: shoppingState, } = this; const item = shoppingState[pid]; if (item) { const selector = `[data-pid="${ pid }"]`; scrollIntoViewIfNeeded(elmMainOverview.querySelector(selector)); elmCartOverview.querySelector(selector)?.remove(); elmMainOverview .querySelector(`[data-add-pid="${ pid }"]`).focus?.(); item.checkout.isInCart = false; item.checkout.orderCount = 0; updateOrderCounts(pid, this); } // console.log('Remove From Cart :: pid ...', pid); } console.log('Remove From Cart :: evt.target ...', evt.target); } function main() { const shoppingState = productList .map(createShoppingItem) .reduce((state, item) => Object.assign(state, { [item.data.pid]: item }), Object.create(null) ); console.log({ shoppingState }) const elmMainOverview = document .querySelector('[data-product-overview]'); const elmShoppingCart = document .querySelector('[data-shopping-cart]'); const elmCartOverview = elmShoppingCart ?.querySelector('[data-cart-overview]'); const elmCartTotal = elmShoppingCart ?.querySelector('[data-cart-total]'); const handlerContext = { target: { elmMainOverview, elmCartOverview, elmCartTotal, }, state: shoppingState, }; elmMainOverview.addEventListener('click', handleAddToCartWithBoundTargetAndState.bind(handlerContext) ); elmCartOverview.addEventListener('click', handleRemoveFromCartWithBoundTargetAndState.bind(handlerContext) ); // initially render product list from shopping state. Object .values(shoppingState) .forEach(item => elmMainOverview.appendChild(item.view.main.cloneNode(true)) ); } main();
 * { margin: 0; padding: 0; } ul, li { list-style: none; } li { position: relative; margin-bottom: 5px; padding: 5px; } li:hover { background-color: #eee; } h3, dl, button { font-size: 12px; } img { max-height: 54px; max-width: 72px; } dl::after { clear: left; } dl dt { float: left; } dl dd::before { content: ': '; } button { position: absolute; right: 5px; bottom: 5px; } button:hover { cursor: pointer; } button:target, button:focus, button:focus-within { outline: 1px solid #06f; } main { position: relative; max-width: 25%; } #mini-cart { position: fixed; right: 60%; top: 0; min-width: 14%; height: 100%; overflow-y: scroll; font-size: 12px; } #mini-cart button { position: unset; } .as-console-wrapper { min-height: 100%!important; width: 60%; top: 0; left: auto!important; right: 0; }
 <main> <ul data-product-overview> </ul> </main> <section id="mini-cart" data-shopping-cart> <a href="#mini-cart"> Mini Cart <output data-cart-total></output> </a> <ul data-cart-overview> </ul> </section>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM