原生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 相关文章推荐
脚本之家贴图转换+转贴工具用到的js代码超级推荐
Apr 05 Javascript
jQuery学习笔记之DOM对象和jQuery对象
Dec 22 Javascript
EasyUI 中 MenuButton 的使用方法
Jul 14 Javascript
最简单的JavaScript验证整数、小数、实数、有效位小数正则表达式
Apr 17 Javascript
JavaScript电子时钟倒计时
Jan 09 Javascript
基于canvas实现的绚丽圆圈效果完整实例
Jan 26 Javascript
jQuery实现拖动剪裁图片作为头像
Dec 28 Javascript
Javascript中click与blur事件的顺序详析
Apr 25 Javascript
React Native模块之Permissions权限申请的实例相机
Sep 28 Javascript
JavaScript使用math.js进行精确计算操作示例
Jun 19 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
Nov 25 Javascript
JS PHP字符串截取函数实现原理解析
Aug 29 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安装问题
2006/10/09 PHP
PHP 和 MySQL 基础教程(一)
2006/10/09 PHP
php中global和$GLOBALS[]的分析之一
2012/02/02 PHP
判断php数组是否为索引数组的实现方法
2013/06/13 PHP
php文件上传的例子及参数详解
2013/12/12 PHP
PHP解决URL中文GBK乱码问题的两种方法
2014/06/03 PHP
php利用header函数下载各种文件
2016/08/24 PHP
PHP处理bmp格式图片的方法分析
2017/07/04 PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
2017/11/10 PHP
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
2015/06/15 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
javascript 中select框触发事件过程的分析
2017/08/01 Javascript
vue数据传递--我有特殊的实现技巧
2018/03/20 Javascript
Vue引入jquery实现平滑滚动到指定位置
2018/05/09 jQuery
bootstrap table插件动态加载表头
2019/07/19 Javascript
JS实现简单tab选项卡切换
2019/10/25 Javascript
浅谈Vue2.4.0 $attrs与inheritAttrs的具体使用
2020/03/08 Javascript
快速解决Vue、element-ui的resetFields()方法重置表单无效的问题
2020/08/12 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
Python的ORM框架SQLObject入门实例
2014/04/28 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
使用python3实现操作串口详解
2019/01/01 Python
Python实现网站表单提交和模板
2019/01/15 Python
原生python实现knn分类算法
2019/10/24 Python
使用Python pip怎么升级pip
2020/08/11 Python
html5使用Canvas绘图的使用方法
2017/11/21 HTML / CSS
简单介绍HTML5中audio标签的使用
2015/09/24 HTML / CSS
运动会开幕式邀请函
2014/02/03 职场文书
大学生个人自荐信样本
2014/03/02 职场文书
优秀教导主任事迹材料
2014/05/09 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
毛主席纪念堂观后感
2015/06/17 职场文书
委托收款证明
2015/06/23 职场文书
spring 项目实现限流方法示例
2022/07/15 Java/Android