AJAX——案例_天气预报

天气预报案例

步骤

  1. 获取北京市天气数据,展示
  2. 搜索城市列表,展示
  3. 点击城市,显示对应天气数据
    index.css代码
复制代码
html,
body {
  height: 100%;
}

body {
  background-image: linear-gradient(135deg, #50B1FF 0%, #1F57D6 100%);
}

.container {
  width: 1200px;
  margin: 0 auto;
  height: 100%;
}

/* 顶部 */
.top-box {
  display: flex;
  padding: 50px;
  justify-content: space-between;
}

/* 日期 */
.top-box .title .data {
  color: white;
  margin-right: 20px;
}

/* 农历 */
.top-box .title .calendar {
  opacity: .72;
}

/* 搜索区域 */
.search-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-box .location {
  display: flex;
  align-items: center;
  margin-right: 20px;
  font-size: 16px;
}

.search-box .location img {
  width: 20px;
  height: 20px;
  margin-right: 7.1px;
}

.search-box .search-city {
  width: 234px;
  height: 32px;
  border: none;
  border-radius: 16px;
  padding-left: 10px;
  background-color: rgba(255, 255, 255, .2);
  color: white;
  font-size: 14px;
}

.search {
  position: relative;
}

/* 搜索列表 */
.search-list {
  width: 100%;
  height: 200px;
  overflow-y: scroll;
  background-color: #fff;
  position: absolute;
  left: 0;
  top: 40px;
  display: none;
}
.search-list.show{
  display: block;
}
.search-list::-webkit-scrollbar{
  display: none;
}
.search-list li{
  color: black;
  font-size: 14px;
  padding: 15px 10px;
}
.search-list li:hover{
  background-color: lightgray;
}

/* 当前天气 */
.weather-box {
  display: flex;
  padding-left: 50px;
  align-items: flex-end;
}

.weather-box .tem-box {
  margin-right: 42px;
  display: flex;
  flex-direction: column;
}

.weather-box .tem-box .temp span{
  font-size: 90px;
  display: inline-block;
  height: 100px;
  margin-bottom: 10px;
  line-height: 100px;
}

.climate-box .air {
  display: inline;
  padding: 5px 10px;
  height: 32px;
  border-radius: 16px;
  background: #65D45A;
  text-align: center;
  line-height: 32px;
  font-family: PingFangSC-Medium;
  font-size: 18px;
  color: #FFFFFF;
  letter-spacing: 0;
  font-weight: 500;
}

.climate-box .weather-list {
  display: flex;
  align-items: flex-end;
  margin-top: 21px;
  margin-bottom: 28px;
}

.climate-box .weather-list li img {
  width: 20px;
  height: 20px;
}

.climate-box .weather-list li {
  margin-right: 20px;
}

.climate-box .weather-list li,
.climate-box .weather-list span {
  display: flex;
  align-items: center;
  font-size: 16px;
}

/* 今日详细天气 */
.today-weather{
  display: flex;
  padding-left: 50px;
}
.today-weather .range-box,
.today-weather .range {
  font-size: 16px;
}

.today-weather .sun-list {
  display: flex;
  align-items: center;
  margin-left: 50px;
}

.today-weather .sun-list li {
  font-size: 16px;
  margin-right: 42px;
}

/* 周天气预报 */
.week-weather-box {
  height: 382px;
  border-radius: 10px;
  background-color: #fff;
  width: 1039px;
  margin: 30px auto;
  padding: 30px;
}
.week-weather-box .title {
  font-size: 20px;
  color: #3A475A;
  letter-spacing: 0;
  font-weight: 600;
}
/* 列表 */
.week-wrap {
  display: flex;
  margin: 0 auto;
  margin-top: 30px;
}
.week-wrap .item {
  width: 150px;
  height: 254px;
  cursor: pointer;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 30px;
}
.week-wrap .item:hover {
  background: #F7FAFF;
  border-radius: 10px;
}

.week-wrap .item span{
  color: #393F48;
}

.week-wrap .item .date-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 4px;
}

.week-wrap .item .date-box .dateFormat {
  font-size: 16px;
  color: #393F48;
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
}
.week-wrap .item .date-box .date {
  font-size: 16px;
  color: #88909D;
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
}

.week-wrap .item img {
  width: 46px;
  height: 46px;
  margin: 12px 0 12px;
}

.week-wrap .item .weather {
  font-size: 16px;
  color: #393F48;
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
  margin-bottom: 4px;
}

.week-wrap .item .temp  {
  font-size: 14px;
  color: #393F48;
  letter-spacing: 0;
  text-align: center;
  font-weight: 500;
  margin-bottom: 10px;
}

.week-wrap .item .wind span {
  font-size: 14px;
  color: #676C74;
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
}

reset.css代码

复制代码
* {
  box-sizing: border-box;
  font-size: 18px;
  ;
  color: white;
}

body,
ul,
h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  padding: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: 100%;
  font-weight: normal;
}

a {
  text-decoration: none;
}

ul {
  list-style: none;
}

img {
  border: 0px;
}

input {
  appearance: none;
  outline: none;
}

input::-webkit-input-placeholder {
  /* WebKit, Blink, Edge */

  color: #E6EBFF;

}

:-moz-placeholder {
  /* Mozilla Firefox 4 to 18 */

  color: #E6EBFF;

}

::-moz-placeholder {
  /* Mozilla Firefox 19+ */

  color: #E6EBFF;

}

input:-ms-input-placeholder {
  /* Internet Explorer 10-11 */

  color: #E6EBFF;

}

input::-ms-input-placeholder {
  /* Microsoft Edge */

  color: #E6EBFF;

}

/* 清除浮动,解决margin-top塌陷 */
.clearfix:before,
.clearfix:after {
  content: '';
  display: table;
}

.clearfix:after {
  clear: both;
}

.clearfix {
  zoom: 1;
}

.fl {
  float: left;
}

.fr {
  float: right;
}

index.js代码

复制代码
/**
 * 目标1:默认显示-北京市天气
 *  1.1 获取北京市天气数据
 *  1.2 数据展示到页面
 */
// 获取并渲染城市天气函数
function getWeather(cityCode) {
    // 1.1 获取北京市天气数据
    myAxios({
      url: 'http://hmajax.itheima.net/api/weather',
      params: {
        city: cityCode
      }
    }).then(result => {
      console.log(result)
      const wObj = result.data
      // 1.2 数据展示到页面
      // 阳历和农历日期
      const dateStr = `<span class="dateShort">${wObj.date}</span>
      <span class="calendar">农历&nbsp;
        <span class="dateLunar">${wObj.dateLunar}</span>
      </span>`
      document.querySelector('.title').innerHTML = dateStr
      // 城市名字
      document.querySelector('.area').innerHTML = wObj.area
      // 当天气温
      const nowWStr = `<div class="tem-box">
      <span class="temp">
        <span class="temperature">${wObj.temperature}</span>
        <span>°</span>
      </span>
    </div>
    <div class="climate-box">
      <div class="air">
        <span class="psPm25">${wObj.psPm25}</span>
        <span class="psPm25Level">${wObj.psPm25Level}</span>
      </div>
      <ul class="weather-list">
        <li>
          <img src="${wObj.weatherImg}" class="weatherImg" alt="">
          <span class="weather">${wObj.weather}</span>
        </li>
        <li class="windDirection">${wObj.windDirection}</li>
        <li class="windPower">${wObj.windPower}</li>
      </ul>
    </div>`
      document.querySelector('.weather-box').innerHTML = nowWStr
      // 当天天气
      const twObj = wObj.todayWeather
      const todayWStr = `<div class="range-box">
      <span>今天:</span>
      <span class="range">
        <span class="weather">${twObj.weather}</span>
        <span class="temNight">${twObj.temNight}</span>
        <span>-</span>
        <span class="temDay">${twObj.temDay}</span>
        <span>℃</span>
      </span>
    </div>
    <ul class="sun-list">
      <li>
        <span>紫外线</span>
        <span class="ultraviolet">${twObj.ultraviolet}</span>
      </li>
      <li>
        <span>湿度</span>
        <span class="humidity">${twObj.humidity}</span>%
      </li>
      <li>
        <span>日出</span>
        <span class="sunriseTime">${twObj.sunriseTime}</span>
      </li>
      <li>
        <span>日落</span>
        <span class="sunsetTime">${twObj.sunsetTime}</span>
      </li>
    </ul>`
      document.querySelector('.today-weather').innerHTML = todayWStr
  
      // 7日天气预报数据展示
      const dayForecast = wObj.dayForecast
      const dayForecastStr = dayForecast.map(item => {
        return `<li class="item">
        <div class="date-box">
          <span class="dateFormat">${item.dateFormat}</span>
          <span class="date">${item.date}</span>
        </div>
        <img src="${item.weatherImg}" alt="" class="weatherImg">
        <span class="weather">${item.weather}</span>
        <div class="temp">
          <span class="temNight">${item.temNight}</span>-
          <span class="temDay">${item.temDay}</span>
          <span>℃</span>
        </div>
        <div class="wind">
          <span class="windDirection">${item.windDirection}</span>
          <span class="windPower">${item.windPower}</span>
        </div>
      </li>`
      }).join('')
      // console.log(dayForecastStr)
      document.querySelector('.week-wrap').innerHTML = dayForecastStr
    })
  }
  
  // 默认进入网页-就要获取天气数据(北京市城市编码:'110100')
  getWeather('110100')
  
  /**
   * 目标2:搜索城市列表
   *  2.1 绑定input事件,获取关键字
   *  2.2 获取展示城市列表数据
   */
  // 2.1 绑定input事件,获取关键字
  document.querySelector('.search-city').addEventListener('input', (e) => {
    console.log(e.target.value)
    // 2.2 获取展示城市列表数据
    myAxios({
      url: 'http://hmajax.itheima.net/api/weather/city',
      params: {
        city: e.target.value
      }
    }).then(result => {
      console.log(result)
      const liStr = result.data.map(item => {
        return `<li class="city-item" data-code="${item.code}">${item.name}</li>`
      }).join('')
      console.log(liStr)
      document.querySelector('.search-list').innerHTML = liStr
    })
  })
  
  /**
   * 目标3:切换城市天气
   *  3.1 绑定城市点击事件,获取城市code值
   *  3.2 调用获取并展示天气的函数
   */
  // 3.1 绑定城市点击事件,获取城市code值
  document.querySelector('.search-list').addEventListener('click', e => {
    if (e.target.classList.contains('city-item')) {
      // 只有点击城市li才会走这里
      const cityCode = e.target.dataset.code
      console.log(cityCode)
      // 3.2 调用获取并展示天气的函数
      getWeather(cityCode)
    }
  })

my-axios.js代码

复制代码
function myAxios(config) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    if (config.params) {
      const paramsObj = new URLSearchParams(config.params)
      const queryString = paramsObj.toString()
      config.url += `?${queryString}`
    }
    xhr.open(config.method || 'GET', config.url)
    xhr.addEventListener('loadend', () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(JSON.parse(xhr.response))
      } else {
        reject(new Error(xhr.response))
      }
    })
    if (config.data) {
      const jsonStr = JSON.stringify(config.data)
      xhr.setRequestHeader('Content-Type', 'application/json')
      xhr.send(jsonStr)
    } else {
      xhr.send()
    }
  })
}

search.js代码

复制代码
// 控制搜索列表,显示/隐藏
const searchList = document.querySelector('.search-list')
// 输入框内容改变时,有城市关键字出现列表,没有则不出现列表
document.querySelector('.search-city').addEventListener('input', e => {
  if (e.target.value.length > 0) {
    searchList.classList.add('show')
  } else {
    searchList.classList.remove('show')
  }
})
// 输入框失焦,隐藏搜索列表
document.querySelector('.search-city').addEventListener('blur', e => {
  // 延迟消失,保证点击获取到城市code后,再隐藏下拉列表
  setTimeout(() => {
    searchList.classList.remove('show')
  }, 500)
})
// 输入框聚焦,显示搜索列表
document.querySelector('.search-city').addEventListener('focus', e => {
  if (e.target.value.length > 0) {
    searchList.classList.add('show')
  }
})

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="./css/reset.css">
  <link rel="stylesheet" href="./css/index.css">
  <title>案例_天气预报</title>
</head>

<body>
  <div class="container">
    <!-- 顶部 -->
    <div class="top-box">
      <div class="title">
        <span class="dateShort">10月28日</span>
        <span class="calendar">农历&nbsp;
          <span class="dateLunar">十月初四</span>
        </span>
      </div>
      <div class="search-box">
        <div class="location">
          <img src="./imgs/定位.png" alt="">
          <span class="area">城市名</span>
        </div>
        <!-- 搜索框+搜索列表 -->
        <div class="search">
          <input type="text" class="search-city" placeholder="搜索城市">
          <ul class="search-list">
            <li class="city-item">北京市</li>
          </ul>
        </div>
      </div>
    </div>
    <!-- 当前天气 -->
    <div class="weather-box">
      <div class="tem-box">
        <span class="temp">
          <span class="temperature">12</span>
          <span>°</span>
        </span>
      </div>
      <div class="climate-box">
        <div class="air">
          <span class="psPm25">55</span>
          <span class="psPm25Level">良</span>
        </div>
        <ul class="weather-list">
          <li>
            <img src="./imgs/小雨-line.png" class="weatherImg" alt="">
            <span class="weather">多云</span>
          </li>
          <li class="windDirection">东南风</li>
          <li class="windPower">2级</li>
        </ul>
      </div>
    </div>
    <div class="today-weather">
      <div class="range-box">
        <span>今天:</span>
        <span class="range">
          <span class="weather">晴</span>
          <span class="temNight">9</span>
          <span>-</span>
          <span class="temDay">14</span>
          <span>℃</span>
        </span>
      </div>
      <ul class="sun-list">
        <li>
          <span>紫外线</span>
          <span class="ultraviolet">强</span>
        </li>
        <li>
          <span>湿度</span>
          <span class="humidity">53</span>%
        </li>
        <li>
          <span>日出</span>
          <span class="sunriseTime">06:38</span>
        </li>
        <li>
          <span>日落</span>
          <span class="sunsetTime">17:18</span>
        </li>
      </ul>
    </div>
    <!-- 周天气预报 -->
    <div class="week-weather-box">
      <div class="title">7日内天气预报</div>
      <ul class="week-wrap">
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temNight">12</span>-
            <span class="temDay">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
        <li class="item">
          <div class="date-box">
            <span class="dateFormat">今天</span>
            <span class="date">10月28日</span>
          </div>
          <img src="./imgs/多云.png" alt="" class="weatherImg">
          <span class="weather">多云</span>
          <div class="temp">
            <span class="temDay">12</span>-
            <span class="temNight">12</span>
            <span>℃</span>
          </div>
          <div class="wind">
            <span class="windDirection">东南风</span>
            <span class="windPower">&lt;3级</span>
          </div>
        </li>
      </ul>
    </div>
  </div>
  <!-- 自己封装myAxios函数 -->
  <script src="./js/my-axios.js"></script>
  <!-- 搜索框+下拉菜单出现逻辑 -->
  <script src="./js/search.js"></script>
  <!-- 核心js -->
  <script src="./js/index.js"></script>
</body>

</html>
相关推荐
excel9 分钟前
webpack 核心编译器 十四 节
前端
excel16 分钟前
webpack 核心编译器 十三 节
前端
腾讯TNTWeb前端团队7 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰11 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪11 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪11 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy12 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom12 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom12 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom12 小时前
React与Next.js:基础知识及应用场景
前端·面试·github