1. 程式人生 > 程式設計 >原生JS實現天氣預報

原生JS實現天氣預報

本文例項為大家分享了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="原生JS實現天氣預報"></div>
 </div>
 <!-- 歷史記錄-->
 <div class="history">
 <div class="la">
  <span>歷史查詢</span>
  <img src="images/more.png" alt="原生JS實現天氣預報">
 </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);
 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,.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,.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,.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,.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,.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,lifestyleurl); /*呼叫渲染方法*/
 searchtext.value = "";
 }
});

 /*手機鍵盤搜尋鍵事件*/
 document.getElementById('search_from').onsubmit = function () {
 searchbtn.click();
 document.activeElement.blur();
 }

 /*主頁面渲染*/
 function rendweather (nowurl,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="原生JS實現天氣預報"> <!-- 天氣圖示 -->
  <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="原生JS實現天氣預報">
    ${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="原生JS實現天氣預報">
      </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,.3)";
  let height = (tqList.length * 0.4) + 1.7;
  historyDiv.style.height = height + 'rem';
  } else {
  flag = true;
  historybtn.style.backgroundColor = "rgba(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();
  }
 });
 }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。