购物车渲染

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    table {
      border: 1px solid;
    }

    td, th {
      border: 1px solid;
    }
  </style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>全选</th>
        <th>商品</th>
        <th>单价</th>
        <th>数量</th>
        <th>小计</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody class="cart-body">
      
    </tbody>
    <tfoot>
      <tr>
        <td><input type="checkbox" class="check_all"></td>
        <td colspan="2">
          <a href="https://www.baidu.com" class="remove_checked">删除选中</a>
        </td>
        <td>
          已选<span class="amounts">0</span></td>
        <td>
          合计:<span class="total">0.00</span>
        </td>
        <td>
          <button>结算</button>
        </td>
      </tr>
    </tfoot>
  </table>

  <script src="js/tools.js"></script>
  <script>
    // 购物车中保存的商品数据的数据结构:
    let cart = [
      {
        id: 1, // 商品编号
        title: '商品标题1', // 商品标题
        price: ((Math.random() * 8.9) + 1).toFixed(2), // 商品价格
        amount: 1, // 商品数量
        checked: true // 是否勾选
      },
      {
        id: 2, // 商品编号
        title: '商品标题2', // 商品标题
        price: ((Math.random() * 8.9) + 1).toFixed(2), // 商品价格
        amount: 3, // 商品数量
        checked: true // 是否勾选
      },
      {
        id: 3, // 商品编号
        title: '商品标题3', // 商品标题
        price: ((Math.random() * 8.9) + 1).toFixed(2), // 商品价格
        amount: 1, // 商品数量
        checked: false // 是否勾选
      }
    ]
  </script>

  <script>
    /* 购物车表格中商品数据及统计数据的渲染 */
    function render() {
      // 遍历 cart 数组,每个元素对应元素表格中一行的显示
      const html = cart.map(product => {
        return (
          `
            <tr>
              <td>
                <input
                  type="checkbox"
                  ${product.checked ? 'checked="checked"' : ''}
                  class="check_product"
                  data-id="${product.id}"
                >
              </td>
              <td>${product.title}</td>
              <td>${product.price}</td>
              <td>
                <button class="minus" data-id="${product.id}">-</button>
                <input size="1" value="${product.amount}" />
                <button class="plus" data-id="${product.id}">+</button>
              </td>
              <td>${(product.price * product.amount).toFixed(2)}</td>
              <td>
                <a href="https://www.baidu.com" class="remove" data-id="${product.id}">删除</a>
              </td>
            </tr>
          `
        )
      }).join('')
      // 将生成的 html 文本设置到 tbody 内部
      $('.cart-body').innerHTML = html

      // 渲染统计数据
      // 合计金额
      const total = cart.reduce((sum, product) => {
        // 累加勾选了的商品的合计金额
        if (product.checked) {
          sum += product.price * product.amount
        }
        return sum
      }, 0)
      $('.total').innerHTML = total.toFixed(2)
      // 已选商品总件数
      const amounts = cart.reduce((sum, product) => {
        if (product.checked) {
          sum += product.amount
        }
        return sum
      }, 0)
      $('.amounts').innerHTML = amounts
      // 是否全选
      const checkAll = cart.every(product => product.checked)
      // const checkAll = cart.every(function(product) {
      //   return product.checked === true
      // })
      $('.check_all').checked = checkAll
    }

    // 初始渲染
    render()
  </script>

  <script>
    /* 点击行中的“删除”,删除购物车中的行 */
    // 利用事件委派的方式,绑定事件
    $('.cart-body').addEventListener('click', event => {
      // 获取最初触发事件的事件源元素
      const src = event.target
      
      // 判断是否为“删除”链接
      if (src.className === 'remove') {
        // 阻止链接跳转
        event.preventDefault()
        // 获取待删除商品的 id(获得的是在标签上绑定的 data-id 自定义属性的值)
        const id = Number(src.dataset.id)
        
        // 在数组中删除对应元素
        cart = cart.filter(product => product.id !== id)
        
        // 重新渲染表格内容
        render()
      }
    }, false)
  </script>

  <script>
    /* 修改数量 */
    // 利用事件委派
    $('.cart-body').addEventListener('click', event => {
      // 获取事件源元素
      const src = event.target
      // 判断是否为+/-按钮
      if (src.className === 'plus' || src.className === 'minus') {
        // 获取待修改数量商品的 id
        const id = Number(src.dataset.id)
        // 根据 id 在 cart 数组中查找 +/-数量的商品
        const product = cart.filter(product => product.id === id)[0]
        // 修改数量
        if (src.className === 'plus') { // 加
          product.amount += 1
        } else { // 减
          if (product.amount <= 1) { // 如果数量已经小于等于1了,就不再减数量了
            return
          }
          product.amount -= 1
        }
        // 重新渲染
        render()
      }
    }, false)
  </script>

  <script>
    /* 商品行前的复选框点击 */
    $('.cart-body').addEventListener('click', event => {
      // 获取事件源
      const src = event.target
      // 判断是否为复选框
      if (src.className === 'check_product') {
        // 获取商品 id
        const id = Number(src.dataset.id)
        // 在数组中查找对应的元素
        const product = cart.filter(product => product.id === id)[0]
        // 修改选中状态
        product.checked = !product.checked
        // 重新渲染
        render()
      }
    }, false)
  </script>

  <script>
    /* 全选与取消全选 */
    $('.check_all').addEventListener('change', event => {
      // 事件源元素的选中状态
      const checked = event.target.checked
      // 修改数组中各元素的选中状态属性
      cart.forEach(product => {
        product.checked = checked
      })
      // 重新渲染
      render()
    }, false)
  </script>

  <script>
    /* 删除选中商品 */
    $('.remove_checked').addEventListener('click', event => {
      // 阻止链接点击跳转
      event.preventDefault()
      // 筛选出数组中未选中的商品
      cart = cart.filter(product => !product.checked)
      // 重新渲染
      render()
    }, false)
  </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值