原生JS实现天气预报


Posted in Javascript onJune 16, 2020

本文实例为大家分享了JS实现天气预报的具体代码,供大家参考,具体内容如下

HTML代码

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport"
  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <link rel="stylesheet" href="tianqi.css" >
 <link rel="stylesheet" href="iconfont/iconfont.css" >
</head>
<body>
 <!-- 搜索 -->
 <div class="search">
 <span>Tq</span>
 <form target="sou" id="search_from">
 <input type="search" placeholder="输入搜索的城市">
 <iframe name="sou" style = "display: none"></iframe>
 </form>
 <div class="search-btn"><img src="images/search.png" alt=""></div>
 </div>
 <!-- 历史记录-->
 <div class="history">
 <div class="la">
  <span>历史查询</span>
  <img src="images/more.png" alt="">
 </div>
 <div class="historys">
 <!-- 历史记录 -->
 </div>
 <div class="clearbtn">
  清除历史记录
 </div>
 </div>
 <!-- 今日天气 -->
 <div class="information">

 </div>
 <!-- 天气预报 -->
 <div class="forecast">

 </div>
 <!-- 生活指数 -->
 <div class="lifestyle">
  <h2>生活指数</h2>
  <div class="lifestyle-box">
  <div class="lifestyle-item" data-indexs="0">
   <i class="iconfont icon-shushidu"></i>
   <span>舒适度指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="1">
   <i class="iconfont icon-3chuanyixiguan"></i>
   <span>穿衣指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="2">
   <i class="iconfont icon-ganmaoyaowu"></i>
   <span>感冒指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="3">
   <i class="iconfont icon-yundong"></i>
   <span>运动指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="4">
   <i class="iconfont icon-lvyou"></i>
   <span>旅游指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="5">
   <i class="iconfont icon-iconset0451"></i>
   <span>紫外线指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="6">
   <i class="iconfont icon-xiche"></i>
   <span>洗车指数</span>
  </div>
  <div class="lifestyle-item" data-indexs="7">
   <i class="iconfont icon-kongqiwuranfenxi"></i>
   <span>空气污染扩散条件指数</span>
  </div>
  </div>
 </div>
 <!-- 生活指数弹窗 -->
 <div class="lifestyle-tc">
 </div>
 <script src="rem.js"></script>
 <script src="Ajax.js"></script>
 <script src="tianqi.js"></script>
</body>
</html>

CSS代码

* {
 margin: 0;
 padding: 0;
}
ul,li {
 list-style: none;
}
body {
 background-size: 120%;
 color: white;
}
.search {
 position: fixed;
 width: 100%;
 height: 0.5rem;
 background-color: rgba(0,0,0,.0);
 display: flex;
 justify-content: space-between;
 align-items: center;
}
#search_from {
 width: 2.8rem;
 height: 0.4rem;
 position: relative;
}
.search > span {
 width: 0.5rem;
 font-size: 0.25rem;
 line-height: 0.5rem;
 text-align: center;
 font-family: "Segoe UI Symbol";
 color: white;
}
.search #search_from > input {
 width: 2.8rem;
 height: 0.4rem;
 border-radius: 0.1rem;
 text-indent: 0.1rem;
 outline: none;
 position: absolute;
 border: none;
 border-bottom: 0.01rem solid white;
 background-color: rgba(255,255,255,.05);
 color: white;
}
.search #search_from > input::-webkit-input-placeholder {
 color: white;
}
.search > .search-btn {
 width: 0.5rem;
 position: relative;
}
.search > .search-btn > img {
 width: 0.25rem;
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%,-50%);
}
.history {
 height: 0.9rem;
 overflow: auto;
 background-color: rgba(255,255,255,.05);
 transition-duration: 0.5s;
}
.historys {
 margin-top: 0.8rem;
 overflow: hidden;
}
.history .history-item {
 display: flex;
 height: 0.4rem;
 border-bottom: 0.01rem dashed #cccccc;
 align-items: center;
 justify-content: space-evenly;
}
.history .history-item > .history-time {
 font-size: 0.14rem;
}
.history .history-item > .history-city {
 font-size: 0.18rem;
}
.history .la {
 height: 0.3rem;
 display: flex;
 position: fixed;
 top: 0.45rem;
 width: 90%;
 background-color: rgba(255,255,255,.0);
 justify-content: space-between;
 font-size: 0.16rem;
 border-bottom: 0.01rem solid white;
 margin: 0.1rem 0.2rem;
 font-family: 幼圆;
 line-height: 0.3rem;
}
.history .la > span {
 color: white;
}
.history .la > img {
 width: 0.2rem;
 height: 0.2rem;
 padding: 0.03rem;
 border: 0.01rem solid #cccccc;
 border-radius: 0.05rem;
}
.clearbtn {
 height: 0.3rem;
 text-align: center;
 text-decoration: underline;
 font-size: 0.2rem;
 margin-top: 0.1rem;
 line-height: 0.3rem;
}
.information {
 /*background-color: gold;*/
}
.now {
 padding-top: 0.2rem;
 display: flex;
 flex-direction: column;
}
.now .city {
 font-size: 0.4rem;
 text-align: center;
}
.now .situation {
 padding-top: 0.2rem;
 display: flex;
 justify-content: space-evenly;
 font-size: 0.15rem;
 align-items: center;
}
.now .situation > img {
 width: 1rem;
 height: 1rem;
 vertical-align: bottom;
}
.now .temp {
 display: flex;
 flex-direction: column;
 align-items: center;
}
.now .temp > h3 {
 font-size: 0.2rem;
 margin-top: 0.1rem;
}
.forecast {
 background-color: rgba(0,0,0,.3);
 margin: 0 0.2rem;
 border-radius: 0.1rem;
}
.forecast-item {
 height: 0.3rem;
 display: flex;
 justify-content: space-between;
 margin: 0.1rem 0.2rem 0;
 padding-top: 0.1rem;
}
.forecast-item:last-of-type {
 padding-bottom: 0.1rem;
}
.forecast-item .forecast-situation > img {
 width: 0.2rem;
 height: 0.2rem;
}
.forecast-item .forecast-situation {
 font-size: 0.16rem;
}
.forecast-temp {
 font-size: 0.18rem;
}
.lifestyle {
 display: none;
 margin: 0 0.2rem;
 background-color: rgba(0,0,0,.3);
 border-radius: 0.1rem;
}
.lifestyle > h2 {
 text-align: center;
 margin-top: 0.2rem;
 font-size: 0.2rem;
 padding-top: 0.15rem;
 font-family: 幼圆;
}
.lifestyle .lifestyle-box {
 display: flex;
 flex-wrap: wrap;
 justify-content: space-between;
}
.lifestyle .lifestyle-box .lifestyle-item {
 display: flex;
 flex-direction: column;
 width: 0.7rem;
 height: 0.4rem;
 font-size: 0.14rem;
 text-align: center;
 padding-top: 0.1rem;
 padding-bottom: 0.05rem;

}
.lifestyle .lifestyle-box .lifestyle-item > i {
 font-size: 0.2rem;
}
.lifestyle .lifestyle-box .lifestyle-item > span {
 white-space: nowrap;
 text-overflow:ellipsis;
 overflow:hidden;
}
.lifestyle-tc {
 height: 100vh;
 position: fixed;
 top: 0;
 left: 0;
 background-color: gold;
 font-family: 幼圆;
 line-height: 0.4rem;

}
.lifestyle-tc .fanghui {
 width: 0.3rem;
 height: 0.3rem;
 position: absolute;
 left: 0.2rem;
 top: 0.1rem;
}
.lifestyle-tc .fanghui > img {
 width: 100%;
}
.lifestyle-tc > h2 {
 font-size: 0.3rem;
 width: 2.2rem;
 margin: 0.3rem auto 0;
 text-align: center;
}
.lifestyle-tc > span {
 width: 100%;
 font-size: 0.2rem;
 margin-top: 1.5rem;
 display: block;
 font-weight: 700;
 text-indent: 0.16rem;
}
.lifestyle-tc > p {
 text-indent: 0.32rem;
 font-size: 0.2rem;
}

JS代码

let searchtext = document.querySelector('.search #search_from > input');
let searchbtn = document.querySelector('.search-btn');
let information = document.querySelector('.information'); //当前天气div
let forecast = document.querySelector(".forecast"); //获取天气预报 div
let lifestyle = document.querySelector('.lifestyle');
 if (localStorage.tq == undefined) { /*如果默认没搜索过 就自动搜索普宁*/
 var tqList = [];
 let defauleCity = "普宁";
 autorend(defauleCity);
 } else { /*如果有搜索记录,就自动搜索最后一次机城市*/
 var tqList = JSON.parse(localStorage.tq);
 let endcityName = tqList[tqList.length - 1].cityName;
 autorend(endcityName);
}

 /* 自动渲染方法*/
 function autorend (cityName) {
 let nowurl = "https://free-api.heweather.net/s6/weather/now?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 let dailyurl = "https://free-api.heweather.net/s6/weather/forecast?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 let lifestyleurl = "https://free-api.heweather.net/s6/weather/lifestyle?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 console.log("执行自动渲染")
 rendweather(nowurl,cityName,dailyurl,lifestyleurl);
}

 function getTime() {
 let date = new Date();
 let year = date.getFullYear();
 let month = date.getMonth() + 1;
 let day = date.getDate();
 let house = date.getHours();
 house = house < 10 ? '0' + house : house;
 let minutes = date.getMinutes();
 minutes = minutes < 10 ? '0' + minutes : minutes;
 let second = date.getMinutes();
 second = second < 10 ? '0' + second : second;
 let time = year + "年 - " + month + "月 - " + day + "日 - " + house + ":" + minutes + ":" + second;
 return time;
 }

 /*搜索按钮事件*/
 searchbtn.addEventListener('click',function () {
 let time = getTime();
 let cityName = searchtext.value;
 /*如果输入框不为空才执行 不加这条件 会导致传入一个空的字符串 导致历史记录添加到一个空的*/
 if (cityName != "") {
 let List = {
  "cityName" : cityName,
  "time" : time
 }
 tqList.push(List);
 localStorage.tq = JSON.stringify(tqList);
 rendhistory(tqList);
 let nowurl = "https://free-api.heweather.net/s6/weather/now?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 let dailyurl = "https://free-api.heweather.net/s6/weather/forecast?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 let lifestyleurl = "https://free-api.heweather.net/s6/weather/lifestyle?location="+cityName+"&key=26be256aca2c43a7bb7f9a72e0f99a6b";
 rendweather(nowurl,cityName,dailyurl,lifestyleurl); /*调用渲染方法*/
 searchtext.value = "";
 }
});

 /*手机键盘搜索键事件*/
 document.getElementById('search_from').onsubmit = function () {
 searchbtn.click();
 document.activeElement.blur();
 }

 /*主页面渲染*/
 function rendweather (nowurl,cityName,dailyurl,lifestyleurl) {
 /*获取今日天气信息*/
 getAjax(nowurl,function (xhr) {
  let databoj = JSON.parse(xhr.response);
  let now = databoj.HeWeather6[0].now;
  if (now == undefined) { /* 如果获取到的为now 说明用户输入的城市有误*/
  if (tqList.length > 1) {//如果长度大于1 说明之前用户正确输入过城市
   tqList.splice(tqList.length - 1 , 1 ); //执行删除最后一个元素 即输入错误的城市
   rendhistory(tqList); // 执行历史记录渲染
   cityName = tqList[tqList.length - 1].cityName; //将城市名赋值为数组最后一个元素 即最后一次正确搜索的城市
  } else if (tqList.length == 1) { /* 如果长度为1 说明现在为止用户没输入一个正确的城市*/
   cityName = "普宁"; //将城市名赋值为 普宁
   // tqList.splice(tqList.length - 1 , 1 );
   tqList.pop(); //删除输入错误的文字
   rendhistory(tqList); //执行历史记录渲染
  }
  autorend(cityName); //最后执行自动渲染
  } else { //如果以上都没错误 说明用户输入的城市正确 正常执行代码
  /* 渲染今日天气*/
  information.innerHTML = `
  <div class="now">
  <span class="city">${cityName}</span>
  <div class="situation">
  <img src="https://cdn.heweather.com/cond_icon/${now.cond_code}.png" alt=""> <!-- 天气图标 -->
  <h1 class="text">${now.cond_txt}</h1> <!-- 天气状况 -->
  <div class="temp">
   <h3 class="tmp">温度:${now.tmp}℃</h3> <!-- 温度 -->
   <h3 class="fl">体感温度:${now.fl}℃</h3>  <!-- 体感温度 -->
  </div>
  </div>
 `;
  /*渲染背景图片*/
  let nowcondtxt = now.cond_code;
  switch(nowcondtxt) {
   case "101":
   case "102":
   case "103":
   case "104":
   document.body.style.backgroundImage = "url('images/2.jpg')";
   break;
   case "100":
   case "200":
   case "201":
   case "202":
   case "203":
   case "204":
   document.body.style.backgroundImage = "url('images/1.jpg')";
   break;
   case "205":
   case "206":
   case "207":
   case "208":
   case "209":
   document.body.style.backgroundImage = "url('images/7.jpg')";
   break;
   case "210":
   case "211":
   case "212":
   case "213":
   document.body.style.backgroundImage = "url('images/8.jpg')";
   break;
   case "300":
   case "301":
   case "302":
   case "303":
   case "304":
   case "305":
   case "306":
   case "307":
   case "308":
   case "309":
   case "310":
   case "311":
   case "312":
   case "313":
   case "314":
   case "315":
   case "316":
   case "317":
   case "318":
   case "399":
   document.body.style.backgroundImage = "url('images/3.jpg')";
   break;
   case "400":
   case "401":
   case "402":
   case "403":
   case "404":
   case "405":
   case "406":
   case "407":
   case "408":
   document.body.style.backgroundImage = "url('images/4.jpg')";
   break;
   case "500":
   case "501":
   case "502":
   case "503":
   case "504":
   case "505":
   case "506":
   case "507":
   case "508":
   document.body.style.backgroundImage = "url('images/5.jpg')";
   break;
   case "509":
   case "510":
   case "511":
   case "512":
   case "513":
   case "514":
   case "515":
   document.body.style.backgroundImage = "url('images/6.jpg')";
   break;
   default:
   document.body.style.backgroundImage = "url('images/9.jpg')";
  }

  /*获取天气预告信息*/
  getAjax(dailyurl,function (xhr) {
   forecast.innerHTML = ""; /*清除之前的渲染*/
   let databoj = JSON.parse(xhr.response);
   let daily = databoj.HeWeather6[0].daily_forecast;
   daily.forEach(function (item,index) {
   /*如果当天天气早上和晚上一样就输出一个 如果不一样 就早上转晚上(天气类型)*/
   var txt = item.cond_txt_d == item.cond_txt_n ? item.cond_txt_d : item.cond_txt_d + "转" + item.cond_txt_n;
   let date = '今天'; /*默认今天*/
   if (index == 1) { /* 第二个赋值为明天*/
    date = "明天";
   } else if (index == 2) { /* 第三个赋值为后天*/
    date = "后天";
   }
   /*渲染天气预报*/
   forecast.innerHTML += `
   <div class="nowday forecast-item">
    <div class="forecast-situation">
    <img src="https://cdn.heweather.com/cond_icon/${item.cond_code_d}.png" alt="">
    ${date} * <span class="txt">${txt}</span>
   </div>
    <div class="forecast-temp">
    <span class="max">${item.tmp_max}°/</span>
    <span class="min">${item.tmp_min}°</span>
    </div>
  </div>`;
   })
  });

  lifestyle.style.display = 'block'; /*显示生活指数模板*/
  /*获取生活指数*/
  getAjax(lifestyleurl,function (xhr) {
   let databoj = JSON.parse(xhr.response);
   let lifestyle = databoj.HeWeather6[0].lifestyle;
   lifestyleclick(lifestyle); /*调用生活指数渲染方法*/
  });
  }
 });
 }

 /*生活指数渲染方法*/
 let lifestyleitem = document.querySelectorAll('.lifestyle-item');
 function lifestyleclick (lifestyle) {
 for (let j = 0; j < lifestyleitem.length; j ++) {
  lifestyleitem[j].onclick = function () {
  let index = lifestyleitem[j].dataset.indexs;
  let li = lifestyle[index];
  let lifestyletc = document.querySelector('.lifestyle-tc');
  lifestyletc.innerHTML = `<div class="fanghui">
    <img src="images/fanghui.png" alt="">
      </div>
    <h2>${lifestyleitem[j].children[1].childNodes[0].data}</h2>
    <span>${li.brf}</span>
    <p>"${li.txt}"</p>`;
  lifestyletc.style.display = 'block';
  /*关闭按钮*/
  let fanghuibtn = document.querySelector('.fanghui');
  console.log(fanghuibtn);
  fanghuibtn.onclick = function () {
   lifestyletc.style.display = 'none';
  }
  }
 }
 }


 //历史记录事件
 let historys = document.querySelector('.historys');
 function rendhistory(tqList) {
 historys.innerHTML = ""; /*每次执行历史记录渲染都清除之前的记录 防止出现重复*/
 tqList.forEach(function (item,index) {
  /*将历史记录写入*/
  historys.innerHTML += `
  <div class="history-item" data-indexs="${index}">
  <span class="history-time">${item.time}</span>
  <span class="history-city">${item.cityName}</span>
  </div>
  `;
 })

 /*获取历史记录div 添加点击事件
 * 点击后跳转点击的城市
 * */
 let historyitem = document.querySelectorAll('.history-item');
 for (let j = 0; j < historyitem.length; j ++) {
  historyitem[j].onclick = function() {
  let index = historyitem[j].dataset.indexs;
  let thecityName = tqList[index].cityName;
  let time = getTime();
  let List = {
   "cityName" : thecityName,
   "time" : time
  }
  tqList.push(List);
  localStorage.tq = JSON.stringify(tqList);
  rendhistory(tqList);
  autorend(thecityName);
  }
 }
 }
 rendhistory(tqList);
 xiala();
 //下拉菜单事件
 function xiala () {
 let historybtn = document.querySelector('.la > img');
 let historyDiv = document.querySelector('.history');
 let clearhistory = document.querySelector('.clearbtn');
 let flag = true;
 historybtn.addEventListener('click',function () {
  if (flag) {
  flag = false;
  historybtn.style.backgroundColor = "rgba(0,0,0,.3)";
  let height = (tqList.length * 0.4) + 1.7;
  historyDiv.style.height = height + 'rem';
  } else {
  flag = true;
  historybtn.style.backgroundColor = "rgba(0,0,0,.0)";
  historyDiv.style.height = '0.9rem';
  }
 });
 clearhistory.addEventListener('click',function () { /*清除历史记录事件*/
  localStorage.removeItem('tq'); /*删除本地存储*/
  tqList = []; /*将数组清空*/
  rendhistory(tqList); /*渲染历史记录*/
  historybtn.click(); /*执行下拉按钮点击*/
 });
 searchtext.addEventListener('click',function () { //点击输入框 如果下拉菜单打开 就关闭
  if (!flag) {
  historybtn.click();
  }
 });
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
超级强大的表单验证
Jun 26 Javascript
复制Input内容的js代码_支持所有浏览器,修正了Firefox3.5以上的问题
Jun 21 Javascript
使用mini-define实现前端代码的模块化管理
Dec 25 Javascript
jQuery实现页面滚动时动态加载内容的方法
Mar 20 Javascript
详解JavaScript对W3C DOM模版的支持情况
Jun 16 Javascript
jQuery中trigger()与bind()用法分析
Dec 18 Javascript
JavaScript中闭包的写法和作用详解
Jun 29 Javascript
vue2.0父子组件及非父子组件之间的通信方法
Jan 21 Javascript
微信小程序 循环及嵌套循环的使用总结
Sep 26 Javascript
关于HTML5的data-*自定义属性的总结
May 05 Javascript
Vue实现的父组件向子组件传值功能示例
Jan 19 Javascript
Vue触发input选取文件点击事件操作
Aug 07 Javascript
vue实现公告栏文字上下滚动效果的示例代码
Jun 16 #Javascript
原生JS实现无缝轮播图片
Jun 24 #Javascript
如何利用Node.js与JSON搭建简单的动态服务器
Jun 16 #Javascript
js+css实现全屏侧边栏
Jun 16 #Javascript
JavaScript装箱及拆箱boxing及unBoxing用法解析
Jun 15 #Javascript
通过实例解析JavaScript for in及for of区别
Jun 15 #Javascript
vue proxy 的优势与使用场景实现
Jun 15 #Javascript
You might like
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
php MessagePack介绍
2013/10/06 PHP
phpStudy访问速度慢和启动失败的解决办法
2015/11/19 PHP
JS中彻底删除JSON对象组成的数组中的元素
2020/09/22 PHP
javascript一些不错的函数脚本代码
2008/09/10 Javascript
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
js如何判断访问是来自搜索引擎(蜘蛛人)还是直接访问
2015/09/14 Javascript
js console.log打印对像与数组用法详解
2016/01/21 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
AngularJS基础 ng-click 指令示例代码
2016/08/01 Javascript
JS制作适用于手机和电脑的通知信息效果
2016/10/28 Javascript
Javascript 高性能之递归,迭代,查表法详解及实例
2017/01/08 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
使用vs code开发Nodejs程序的使用方法
2017/09/21 NodeJs
JS动画实现回调地狱promise的实例代码详解
2018/11/08 Javascript
[09:13]2014DOTA2国际邀请赛 中国区预选赛coser表演
2014/05/23 DOTA
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
[01:28:44]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第一场 1月10日
2021/03/11 DOTA
python编码最佳实践之总结
2016/02/14 Python
python 寻找list中最大元素对应的索引方法
2018/06/28 Python
Python使用pickle模块实现序列化功能示例
2018/07/13 Python
PyQt5 在label显示的图片中绘制矩形的方法
2019/06/17 Python
Python3 翻转二叉树的实现
2019/09/30 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
3个CCIE对一个工程师的面试题
2012/05/06 面试题
《梅兰芳学艺》教学反思
2014/02/24 职场文书
小学生十佳少年事迹材料
2014/08/20 职场文书
五四青年节的活动方案
2014/08/20 职场文书
教师国庆节演讲稿范文2014
2014/09/21 职场文书
2014年保卫工作总结
2014/12/05 职场文书
工作经验交流材料
2014/12/30 职场文书
入党宣誓仪式主持词
2015/06/29 职场文书
Apache压力测试工具的安装使用
2021/03/31 Servers
Python 类,对象,数据分类,函数参数传递详解
2021/09/25 Python