AJAX——案例

1.商品分类

需求:尽可能同时展示所有商品分类到页面上

步骤:

  1. 获取所有的一级分类数据
  2. 遍历id,创建获取二级分类请求
  3. 合并所有二级分类Promise对象
  4. 等待同时成功后,渲染页面

index.html代码

<!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>
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>
  <!-- 大容器 -->
  <div class="container">
    <div class="sub-list">
      <div class="item">
        <h3>分类名字</h3>
        <ul>
          <li>
            <a href="javascript:;">
              <img src="http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/img/category%20(9).png" />
              <p>巧克力</p>
            </a>
          </li>
          <li>
            <a href="javascript:;">
              <img src="http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/img/category%20(9).png" />
              <p>巧克力</p>
            </a>
          </li>
          <li>
            <a href="javascript:;">
              <img src="http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/img/category%20(9).png" />
              <p>巧克力</p>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /**
     * 目标:把所有商品分类"同时"渲染到页面上
     *  1. 获取所有一级分类数据
     *  2. 遍历id,创建获取二级分类请求
     *  3. 合并所有二级分类Promise对象
     *  4. 等待同时成功后,渲染页面
    */
    // 1. 获取所有一级分类数据
    axios({
      url:'http://hmajax.itheima.net/api/category/top'
    }).then(result => {
      console.log(result)
      // 2. 遍历id,创建获取二级分类请求
      const secPromiseList = result.data.data.map(item => {
        return axios({
          url:'http://hmajax.itheima.net/api/category/sub',
          params: {
            id: item.id  // 一级分类id
          }
        })
      })
      console.log(secPromiseList) // [二级分类请求Promise对象,二级分类请求Promise对象......]
      // 3. 合并所有二级分类Promise对象
      const p = Promise.all(secPromiseList)
      p.then(result => {
        console.log(result)
        // 4. 等待同时成功后,渲染页面
        const htmlStr = result.map(item => {
          const dataObj = item.data.data // 取出关键数据对象
          return `<div class="item">
        <h3>${dataObj.name}</h3>
        <ul>
          ${dataObj.children.map(item => {
            return `<li>
            <a href="javascript:;">
              <img src="${item.picture}">
              <p>${item.name}</p>
            </a>
          </li>`
          }).join('')}
        </ul>
      </div>`
        }).join('')

        console.log(htmlStr)
        document.querySelector('.sub-list').innerHTML = htmlStr
      })
    })

  </script>
</body>

</html>

index.css代码

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
a {
  text-decoration: none;
  color: #333;
}
ul {
  list-style: none;
}
.container {
  width: 980px;
  margin: 0 auto;
}
.container h3 {
  font-size: 18px;
  color: #666;
  font-weight: normal;
  text-align: center;
  line-height: 100px;
}
.container .sub-list {
  background-color: #fff;
}
.container .sub-list ul {
  display: flex;
  padding: 0 32px;
  flex-wrap: wrap;
}
.container .sub-list ul li {
  width: 168px;
  height: 160px;
}
.container .sub-list ul li a {
  text-align: center;
  display: block;
  font-size: 14px;
}
.container .sub-list ul li a img {
  width: 100px;
  height: 100px;
}
.container .sub-list ul li a p {
  line-height: 40px;
}
.container .sub-list ul li a:hover {
  color: var(--xtx-color);
}
.ref-goods {
  background-color: #fff;
  margin-top: 20px;
  position: relative;
}
.ref-goods .head .xtx-more {
  position: absolute;
  top: 20px;
  right: 20px;
}
.ref-goods .head .tag {
  text-align: center;
  color: #999;
  font-size: 20px;
  position: relative;
  top: -20px;
}
.ref-goods .body {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  padding: 0 65px 30px;
}
.ref-goods .body .none {
  height: 220px;
  text-align: center;
  width: 100%;
  line-height: 220px;
  color: #999;
}

2.学习反馈-省市区切换

需求:完成省市区切换效果

步骤:

  1. 设置省份数据到下拉菜单
  2. 切换省份,设置城市数据到下拉菜单,并清空地区下拉菜单
  3. 切换城市,设置地区数据到下拉菜单

index.js

/**
 * 目标1:完成省市区下拉列表切换
 *  1.1 设置省份下拉菜单数据
 *  1.2 切换省份,设置城市下拉菜单数据,清空地区下拉菜单
 *  1.3 切换城市,设置地区下拉菜单数据
 */
// 1.1 设置省份下拉菜单数据
axios({
    url: 'http://hmajax.itheima.net/api/province'
  }).then(result => {
    const optionStr = result.data.list.map(pname => `<option value="${pname}">${pname}</option>`).join('')
    document.querySelector('.province').innerHTML = `<option value="">省份</option>` + optionStr
  })
  
  // 1.2 切换省份,设置城市下拉菜单数据,清空地区下拉菜单
  document.querySelector('.province').addEventListener('change', async e => {
    // 获取用户选择省份名字
    // console.log(e.target.value)
    const result = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname: e.target.value } })
    const optionStr = result.data.list.map(cname => `<option value="${cname}">${cname}</option>`).join('')
    // 把默认城市选项+下属城市数据插入select中
    document.querySelector('.city').innerHTML = `<option value="">城市</option>` + optionStr
  
    // 清空地区数据
    document.querySelector('.area').innerHTML = `<option value="">地区</option>`
  })
  
  // 1.3 切换城市,设置地区下拉菜单数据
  document.querySelector('.city').addEventListener('change', async e => {
    console.log(e.target.value)
    const result = await axios({url: 'http://hmajax.itheima.net/api/area', params: {
      pname: document.querySelector('.province').value,
      cname: e.target.value
    }})
    console.log(result)
    const optionStr = result.data.list.map(aname => `<option value="${aname}">${aname}</option>`).join('')
    console.log(optionStr)
    document.querySelector('.area').innerHTML = `<option value="">地区</option>` + optionStr
  })
  
  /**
   * 目标2:收集数据提交保存
   *  2.1 监听提交的点击事件
   *  2.2 依靠插件收集表单数据
   *  2.3 基于axios提交保存,显示结果
   */
  // 2.1 监听提交的点击事件
  document.querySelector('.submit').addEventListener('click', async () => {
    // 2.2 依靠插件收集表单数据
    const form = document.querySelector('.info-form')
    const data = serialize(form, { hash: true, empty: true })
    console.log(data)
    // 2.3 基于axios提交保存,显示结果
    try {
      const result = await axios({
        url: 'http://hmajax.itheima.net/api/feedback',
        method: 'POST',
        data
      })
      console.log(result)
      alert(result.data.message)
    } catch (error) {
      console.dir(error)
      alert(error.response.data.message)
    }
  })

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<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">
  <!-- 初始化样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css">
  <!-- 引入bootstrap.css -->
  <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
  <!-- 核心样式 -->
  <link rel="stylesheet" href="./css/index.css">
  <title>学习反馈</title>
</head>

<body>
  <div class="container">
    <h4 class="stu-title">学习反馈</h4>
    <img class="bg" src="./img/head.png" alt="">
    <div class="item-wrap">
      <div class="hot-area">
        <span class="hot">热门校区</span>
        <ul class="nav">
          <li><a target="_blank" href="http://bjcp.itheima.com/">北京</a> </li>
          <li><a target="_blank" href="http://sh.itheima.com/">上海</a> </li>
          <li><a target="_blank" href="http://gz.itheima.com/">广州</a> </li>
          <li><a target="_blank" href="http://sz.itheima.com/">深圳</a> </li>
        </ul>
      </div>
      <form class="info-form">
        <div class="area-box">
          <span class="title">地区选择</span>
          <select name="province" class="province">
            <option value="">省份</option>
          </select>
          <select name="city" class="city">
            <option value="">城市</option>
          </select>
          <select name="area" class="area">
            <option value="">地区</option>
          </select>
        </div>
        <div class="area-box">
          <span class="title">您的称呼</span>
          <input type="text" name="nickname" class="nickname"  value="播仔">
        </div>
        <div class="area-box">
          <span class="title">宝贵建议</span>
          <textarea type="text" name="feedback" class="feedback" placeholder="您对AJAX阶段课程宝贵的建议"></textarea>
        </div>
        <div class="area-box">
          <button type="button" class="btn btn-secondary submit">
            确定提交
          </button>
        </div>
      </form>
    </div>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.0/axios.min.js"></script>
  <script src="./js/form-serialize.js"></script>
  <!-- 核心代码 -->
  <script src="./js/index.js"></script>
</body>

</html>

index.css

.container {
  width: 1000px;
  padding-top: 20px;
  margin: 0 auto 0;
  position: relative;
}

.container .stu-title {
  font-weight: 900;
  font-size: 36px;
}

.container .bg {
  display: block;
  width: 100%;
}

.item-wrap .hot-area {
  display: flex;
  margin-bottom: 20px;
}

.item-wrap .hot-area .hot {
  color: #c32f32;
  font-weight: 600;
  margin-right: 20px;
}


.item-wrap .nav {
  display: flex;
}

.item-wrap .nav li {
  margin-right: 10px;
}

.item-wrap .nav li a {
  text-decoration: none;
  color: black;
}


.item-wrap .title {
  font-weight: 600;
  white-space: nowrap;
  margin-right: 20px;
}

.item-wrap select {
  width: 150px;
  height: 40px;
  font-size: 14px;
  color: black;
  letter-spacing: 0;
  font-weight: 400;
  background: #FFFFFF;
  border: 1px solid rgba(232, 232, 233, 1);
  border-radius: 4px;
  padding: 10px;
  outline: none;
  margin-right: 10px;

}

.item-wrap select option {
  font-weight: normal;
  display: block;
  white-space: nowrap;
  min-height: 1.2em;
  padding: 0px 2px 1px;
  font-size: 16px;

}

.item-wrap input {
  font-weight: normal;
  display: block;
  white-space: nowrap;
  min-height: 1.2em;
  padding: 0px 2px 1px;
  height: 40px;
  font-size: 16px;
  border: 1px solid rgba(232, 232, 233, 0.682);
  color: black;
}

.item-wrap .feedback {
  width: 400px;
  height: 150px;
  border: 1px solid rgba(232, 232, 233, 0.682);
}

.item-wrap .area-box {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
}

.feedback::-webkit-input-placeholder {
  /* WebKit browsers */
  color: #BFBFBF;
}

.feedback:-moz-placeholder {
  /* Mozilla Firefox 4 to 18 */
  color: #BFBFBF;
}

.feedback::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: #BFBFBF;
}

.feedback:-ms-input-placeholder {
  /* Internet Explorer 10+ */
  color: #BFBFBF;
}
相关推荐
一个处女座的程序猿O(∩_∩)O2 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink5 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者6 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-7 小时前
验证码机制
前端·后端
燃先生._.8 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖9 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235249 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_7482402510 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar10 小时前
纯前端实现更新检测
开发语言·前端·javascript