搜索商品的小案例

<!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>查询商品小案例</title>
  <style>
    table {
      width: 400px;
      border: 1px solid #000;
      border-collapse: collapse;
      margin: 0 auto;
    }

    td,
    th {
      border: 1px solid #000;
      text-align: center;
    }

    input {
      width: 50px;
    }

    .search {
      width: 600px;
      margin: 20px auto;
    }
  </style>
</head>
<body>
  <div class="search"> 按照价格查询: <input type="text" class="start" /> - <input type="text" class="end" /> <button class="search-price">搜索</button> 按照商品名称查询: <input type="text" class="product" /> <button class="search-pro">查询</button>    </div>
    <table>
      <thead>
        <tr>
          <th>id</th>
          <th>产品名称</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        <!-- 模板结构 -->
        <!-- <tr>
          <td>1</td>
          <td>小米</td>
          <td>3999</td>
        </tr> -->
      </tbody>
    </table>
    <script>
      // 数据源
      var data = [
        {
          id: 1,
          pname: '小米',
          price: 3999
        },
        {
          id: 2,
          pname: 'oppo',
          price: 999
        },
        {
          id: 3,
          pname: '荣耀',
          price: 1299
        },
        {
          id: 4,
          pname: '华为',
          price: 1999
        },
        {
          id: 5,
          pname: '华为',
          price: 6799
        }
      ]

      // 获取元素
      var tbody = document.querySelector('tbody ')
      // 输入开始价格的输入框
      var startIpt = document.querySelector('.start')
      // 输入结束价格的输入框
      var endIpt = document.querySelector('.end')
      // 搜索按钮
      var search_price_btn = document.querySelector('.search-price')
      // 输入商品名的输入框
      var proIpt = document.querySelector('.product')
      var search_pro_btn = document.querySelector('.search-pro')

      // 封装渲染表格数据的处理函数 -> 2中方法,任选其一
      // 第一种方法:先创建 tr 元素,然后为 tr 元素赋值,再让 父级 tbody 追加 tr 元素
      function renderData1(data) {
        // 清空表格
        tbody.innerHTML = ''
        // 遍历数组
        data.forEach(item => {
          // 创建 tr 元素
          var tr = document.createElement('tr')
          // 为 tr 赋值,渲染出表格中的内容
          tr.innerHTML = '<td>' + item.id + '</td>' + '<td>' + item.pname + '</td>' + '<td>' + item.price + '</td>'
          // 让父级 tbody 追加 tr 元素
          tbody.appendChild(tr)
        })
      }
      
      // 第二种方法:先准备好模板字符串,再通过 insertAdjacentHTML 将模板字符串追加到 tbody 元素中
      function renderData2(data) {
        // 清空表格
        tbody.innerHTML = ''
        // 遍历数据
        data.forEach(item => {
          // 模板字符串
          var str = '<tr><td>' + item.id + '</td><td>' + item.pname + '</td><td>' + item.price + '</td>'
          // 让 tbody 追加模板字符串
          tbody.insertAdjacentHTML('beforeend', str)
        })
      }

      // 调用函数,渲染UI页面,以防止页面空白
      renderData2(data) // 这里选用第二种方法

      // 封装对用户输入的值做进一步处理的函数
      function handleVal(target) {
        // 如果用户没有输入其实价格,则默认价格为 0
        if (!target.value.trim() && target.className === 'start') {
          return 0
        }
        // 如果用户没有输入结束价格,则默认价格为现有的最大价格
        if(!target.value.trim() && target.className === 'end') {
          var priceArr = data.map(item => item.price)
          var maxPrice = Math.max(...priceArr)
          return maxPrice
        }
        // 如果用户输入了数值,则返回用户输入的值
        return target.value.trim()
      }

      // 根据价格搜索商品的处理函数
      function handlePriceSearch() {
        // 获取文本输入框中的值,并调用函数handleVal 对值做进一步处理
        var startPri = handleVal(startIpt)
        var endPri = handleVal(endIpt)
        var newData = data.filter(item => item.price >= startPri && item.price <= endPri)
        renderData2(newData)
      }

      // 点击搜索按钮调用处理函数搜索商品
      search_price_btn.onclick = handlePriceSearch
    
      // 为查询按钮绑定点击事件
      /* search_pro_btn.onclick = function() {
        // 获取文本框中的值
        var proName = proIpt.value.trim()
        // 创建一个新数组
        var newArr = []
        // 查找满足条件的值
        data.some(item => {
          if (item.pname === proName) {
            // 将找到的item项追加到新数组中
            newArr.push(item)
            // 固定写法,some 只能返回布尔值,返回 true 表示已找到,此时会终止代码退出循环
            return true
          }
        })
        // 重新渲染数据
        renderData2(newArr)
      } */
      // 这个地方除了可以使用 some,感觉 find 也可以,而且使用起来好像更简单。
      // 因为键盘弹起事件中也需要用到,所以这里将其封装为函数
      function handleProSearch() {
        // 获取文本框中的值
        var proName = proIpt.value.trim()
        // 准备一个新数组
        var newArr = []
        // find 直接返回找到的那一项
        var findItem = data.find(item => item.pname === proName)
        // 追加数据
        newArr.push(findItem)
        // 渲染数据
        renderData2(newArr)
      }
      search_pro_btn.onclick = handleProSearch

      // 封装键盘弹起事件的处理函数
      function handleKeyup(e) {
        // 按下 esc 键清空输入框中的内容
        if (e.keyCode === 27) {
          this.value = ''
          // 如果用户将起始价格和结束价格都清空,则重新渲染完整的数据
          if (!startIpt.value && !endIpt.value) {
            // 1、直接调用函数渲染:刚清空输入框页面就被重新渲染了,个人感觉这种效果更好。
            renderData2(data)
            // 2、强制刷新页面:停顿一下再渲染页面,
            // location.reload()
          }
        } else if (e.keyCode === 13) {
          // 按下回车键搜索商品
          handlePriceSearch()
        }
      }
      // 为开始价格的输入框绑定键盘弹起事件
      startIpt.onkeyup = handleKeyup
      // 为结束价格的输入框绑定键盘弹起事件
      endIpt.onkeyup = handleKeyup

      // 为输入商品名的输入框绑定键盘弹起事件
      // 因为这里与起始价格和结束价格输入框的处理有些不同,所以单独写一个处理函数
      proIpt.onkeyup = function(e) {
        // 按下 esc 键清空输入框中的内容
        if (e.keyCode === 27) {
          this.value = ''
          // 将输入框中的内容清空后,重新渲染完整的数据
          renderData2(data)
          // location.reload() // 上面的效果更好些,保留上面的。
        } else if (e.keyCode === 13) {
           // 按下回车键搜索商品
          handleProSearch()
        }
      }
    </script>
</body>
</html>

<!-- 
  写代码时注意:先实现主要功能,再完善细节!这样不会乱,否则需要频繁的大范围改动代码!
  
  一、主要功能:
  1、实现通过价格区间搜索商品的功能。
  2、实现通过商品名搜索商品的功能。
  二、细节:
  1、用户没有输入起始价格,则默认价格为0;用户没有输入结束价格,则默认价格为现有价格中的最大值。
  2、按下 esc 键清空输入框中的内容;按下回车键搜索商品。
  3、起始价格和结束价格的输入框内容都清空后,重新渲染完整的数据页面;而输入商品名的输入框只要内容被清空后,则重新渲染完整数据。
-->

<!-- 
  此案例中存在的BUG:
  1、只能实现“精准搜索”。
  2、只能搜索到第一个满足条件的商品。(无论是 some(返回布尔值) 还是 find(直接返回查找到的那一项) 都只会查找到第一个满足的值)
 -->

​​​​​​​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值