Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
家好,不知道大家聽說過 Vanilla JavaScript 這款 框架嗎?最近我在瀏覽國外的一些技術網站時,這個詞出現的頻率實在是在太高了,好多框架都宣稱自己是基于 Vanilla JavaScript。那到底什么是 Vanilla JavaScript 呢?
vanilla-js.com 官方網站是這樣介紹的:Vanilla JS is a fast, lightweight, cross-platform framework for building incredible, powerful JavaScript applications.
Vanilla JS 是一個快速、輕量級、跨平臺的JavaScript框架。我們可以用它構建強大的JavaScript應用程序。
大家是不是覺得很這個框架很強大呢,哈哈,不和大家賣關子了,Vanilla JavaScript 就是原生JavaScript。現在做前端項目,大家是不是都在用vue、react這樣的框架呢,遇到一些復雜的功能和效果,就是想尋找是否有相關的插件呢,很少想到手工實現呢?大家是否想過這些問題,如果沒有這些前端框架,我們是否還能順利完成項目呢?
本篇文章,我將和大家一起使用原生 JavaScript 創建一個簡單的天氣查詢應用。
這是一款界面十分簡潔大氣的天氣查詢應用,大概的需求是這樣的:
大概就是這些簡單的需求,具體界面長啥樣,如下圖所示:
交互效果,請看下段視頻展示:
<script src="https://lf6-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
是不是很漂亮呢,那還不趕緊和我一起動手完成這個應用。
1、申請天氣查詢API首先我們需要尋找一個天氣查詢的API,方便我們集成。這樣的API市面上比較多,比如阿里云市場就可以申請,不過好像是收費的,調用起來還需要后端配合,為了讓大家快速上手,我推薦大家去國外 https://openweathermap.org/ 這個網站申請一個免費的API,之所以用這個,調用方便,通過URL地址傳參就能進行調用,雖然高級功能需要付費,但是做個簡單的天氣查詢應用,免費功能已經夠用。
2、下載天氣圖標這個項目中,我們需要用天氣圖標直觀的展示天氣情況,這里我建議用SVG格式的圖標,主要原因是矢量的形式,不失真,還有一個原因就是我們能根據自己的需要很方便的改變顏色。
下圖是我在網絡上找到的圖標,喜歡的可以私信我進行獲取。
基本工作準備完后,我們就開始動手實踐吧!
我們先定義兩個<section>區域,第一個 section 區域,包含了應用名稱、一個表單和一個提示信息文本。提示信息文本默認是沒內容的,只有在特定的條件下才能顯示,比如城市名稱不正確或者重復輸入已查詢過的城市信息。
第二個 section 區域用來展示已查詢過的城市列表,默認的情況,這個區域是沒有查詢信息的,只有輸入城市信息,成功調用天氣API接口時,才能顯示相關信息。
初始化的 HTML 結構如下:
<section class="top-banner">
<div class="container">
<h1 class="heading">Simple Weather App</h1>
<form>
<input type="text" placeholder="Search for a city" autofocus>
<button type="submit">SUBMIT</button>
<span class="msg"></span>
</form>
</div>
</section>
<section class="ajax-section">
<div class="container">
<ul class="cities"></ul>
</div>
</section>
autofocus 頁面初始化時,輸入焦點默認聚焦輸入表單
你會注意到第二個 section 區域里,沒有城市列表信息,這部分的結構,是通過JS代碼動態生成的,基本結構如下:
<li class="city">
<h2 class="city-name" data-name="...">
<span>...</span>
<sup>...</sup>
</h2>
<span class="city-temp">...<sup>°C</sup></span>
<figure>
<img class="city-icon" src="..." alt="...">
<figcaption>...</figcaption>
</figure>
</li>
<sup> 用來展示上角標文本。
創建完基本的結構后,我們需要用 CSS 進行美化,如下代碼所示我們定義了全局的顏色自定義變量,以及一些基礎的樣式外觀,示例代碼如下:
:root {
--bg_main: #0a1f44;
--text_light: #fff;
--text_med: #53627c;
--text_dark: #1e2432;
--red: #ff1e42;
--darkred: #c3112d;
--orange: #ff8c00;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-weight: normal;
}
button {
cursor: pointer;
}
input {
-webkit-appearance: none;
}
button,
input {
border: none;
background: none;
outline: none;
color: inherit;
}
img {
display: block;
max-width: 100%;
height: auto;
}
ul {
list-style: none;
}
body {
font: 1rem/1.3 "Roboto", sans-serif;
background: var(--bg_main);
color: var(--text_dark);
padding: 50px;
}
基礎樣式完成后,我們需要為兩個 Section 區域添加樣式
1、Section #1 Styles
首先我們需要完善下 Section 區域一的樣式,當前屏幕大于 >700px,界面如下圖所示:
當前屏幕小與等于700px時,應用名稱、輸入框、按鈕各占一行,界面如下圖所示:
完后的樣式代碼如下所示:
.top-banner {
color: var(--text_light);
}
.heading {
font-weight: bold;
font-size: 4rem;
letter-spacing: 0.02em;
padding: 0 0 30px 0;
}
.top-banner form {
position: relative;
display: flex;
align-items: center;
}
.top-banner form input {
font-size: 2rem;
height: 40px;
padding: 5px 5px 10px;
border-bottom: 1px solid;
}
.top-banner form input::placeholder {
color: currentColor;
}
.top-banner form button {
font-size: 1rem;
font-weight: bold;
letter-spacing: 0.1em;
padding: 15px 20px;
margin-left: 15px;
border-radius: 5px;
background: var(--red);
transition: background 0.3s ease-in-out;
}
.top-banner form button:hover {
background: var(--darkred);
}
.top-banner form .msg {
position: absolute;
bottom: -40px;
left: 0;
max-width: 450px;
min-height: 40px;
}
@media screen and (max-width: 700px) {
.top-banner form {
flex-direction: column;
}
.top-banner form input,
.top-banner form button {
width: 100%;
}
.top-banner form button {
margin: 20px 0 0 0;
}
.top-banner form .msg {
position: static;
max-width: none;
min-height: 0;
margin-top: 10px;
}
}
2、Section #2 Styles
這部分區域,我們將用到網格布局進行展示城市天氣信息列表,當然這部分區域也是要支持響應式的。
如果當前屏幕大于1000px,我們一行將展示4個城市信息,如下圖所示:
當屏幕在 (>700px and ≤1000px) 時,顯示三列;當屏幕 (>500px and ≤700px) 時;顯示兩列;當屏幕 (≤500px) 時,則顯示一列。
以下是基于媒介屬性的網格布局:
.ajax-section {
margin: 50px 0 20px;
}
.ajax-section .cities {
display: grid;
grid-gap: 32px 20px;
grid-template-columns: repeat(4, 1fr);
}
@media screen and (max-width: 1000px) {
.ajax-section .cities {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (max-width: 700px) {
.ajax-section .cities {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (max-width: 500px) {
.ajax-section .cities {
grid-template-columns: repeat(1, 1fr);
}
}
為了讓每個城市信息的效果更加生動,類似個卡片,我們可以使用 ::after 偽元素,利用 bottom 屬性添加一個背景陰影的效果。
在這個卡片上,當接口請求成功時,我們需要展示當前城市的名稱、所屬國家、溫度及具體的天氣,天氣通過圖標和文字結合的形式進行展示,如下所示:
.ajax-section .city {
position: relative;
padding: 40px 10%;
border-radius: 20px;
background: var(--text_light);
color: var(--text_med);
}
.ajax-section .city::after {
content: ’’;
width: 90%;
height: 50px;
position: absolute;
bottom: -12px;
left: 5%;
z-index: -1;
opacity: 0.3;
border-radius: 20px;
background: var(--text_light);
}
.ajax-section figcaption {
margin-top: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.ajax-section .city-temp {
font-size: 5rem;
font-weight: bold;
margin-top: 10px;
color: var(--text_dark);
}
.ajax-section .city sup {
font-size: 0.5em;
}
.ajax-section .city-name sup {
padding: 0.2em 0.6em;
border-radius: 30px;
color: var(--text_light);
background: var(--orange);
}
.ajax-section .city-icon {
margin-top: 10px;
width: 100px;
height: 100px;
}
通過以上的操作我們把應用的樣式弄完了,接下來我們開始完成核心的腳本代碼。
1、當按鈕提交時
當用戶點擊按鈕或者按回車鍵時,我們的程序應該這么做:
代碼的基礎結構如下所示:
const form = document.querySelector(".top-banner form");
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
});
接下來我們來處理,如何展示城市列表的數據信息。
2、執行 AJAX 請求
假設第一次進入頁面,城市列別還沒相關信息,這種情況我們只需要發送 OpenWeatherMap 的 API 請求即可,遵循 API 文檔,我們只需要傳遞申請的 API 的 key,城市名稱即可,如下段代碼所示:
const apiKey = "YOUR_OWN_KEY";
const inputVal = input.value;
...
const url = `https://api.openweathermap.org/data/2.5/weather?q=${inputVal}&appid=${apiKey}&units=metric`;
基于文檔說明,我們通過JS自帶的 fetch() 請求方法,處理AJAX請求,具體的示例代碼如下:
...
fetch(url)
.then(response => response.json())
.then(data => {
// do stuff with the data
})
.catch(() => {
msg.textContent = "Please search for a valid city ";
});
下圖為我們請求過來的數據格式:
3、編寫單個城市卡片組件
數據請求成功后,我們就需要處理數據,展示城市的天氣信息,填充到城市列表展示區域,相關代碼如下所示:
const { main, name, sys, weather } = data;
const icon = `https://openweathermap.org/img/wn/${
weather[0]["icon"]
}@2x.png`;
const li = document.createElement("li");
li.classList.add("city");
const markup = `
<h2 class="city-name" data-name="${name},${sys.country}">
<span>${name}</span>
<sup>${sys.country}</sup>
</h2>
<div class="city-temp">${Math.round(main.temp)}<sup>°C</sup>
</div>
<figure>
<img class="city-icon" src=${icon} alt=${weather[0]["main"]}>
<figcaption>${weather[0]["description"]}</figcaption>
</figure>
`;
li.innerHTML = markup;
list.appendChild(li);
這段代碼我們兩點需要說明下:
4、重置表單輸入接口請求完后,我們需要將表單輸入框置空,提示信息置空,輸入焦點重新聚焦到輸入框。示例代碼如下:
msg.textContent = "";
form.reset();
input.focus();
5、替換成自己的個性化圖標
如下圖所示,以下接口自帶的幾種圖片我們需要一一對應成我們自己個性化的圖標,名稱也保持一致,放到我們的圖片文件夾即可:
對應代碼需要做相應的修改,如下所示:
//BEFORE
const icon = `https://openweathermap.org/img/wn/${
weather[0]["icon"]
}@2x.png`;
//AFTER
const icon = `images/${
weather[0]["icon"]
}.svg`;
6、阻止相同城市請求
為了防止多次提交同一個城市的信息 ,我們需要進行去重,要不就會發生如下的效果,并不是我們期望的:
這是個糟糕的用戶體驗,除此之外,還需要處理一個情況,如果一個城市,比如 Athens,在希臘是雅典,在美國為雅典-克拉克縣,這種情況不能認為是重復的請求,我們支持用逗號分隔輸入,前面城市后面國家簡寫。
基于以上的去重需求,剛才前面提及到的自定義 data-name 就派上用場了,完后的代碼如下所示:
...
//1
const listItems = list.querySelectorAll(".ajax-section .city");
const listItemsArray = Array.from(listItems);
if (listItemsArray.length > 0) {
//2
const filteredArray = listItemsArray.filter(el => {
let content = "";
//athens,gr
if (inputVal.includes(",")) {
//athens,grrrrrr->invalid country code, so we keep only the first part of inputVal
if (inputVal.split(",")[1].length > 2) {
inputVal = inputVal.split(",")[0];
content = el.querySelector(".city-name span").textContent.toLowerCase();
} else {
content = el.querySelector(".city-name").dataset.name.toLowerCase();
}
} else {
//athens
content = el.querySelector(".city-name span").textContent.toLowerCase();
}
return content == inputVal.toLowerCase();
});
//3
if (filteredArray.length > 0) {
msg.textContent = `You already know the weather for ${
filteredArray[0].querySelector(".city-name span").textContent
} ...otherwise be more specific by providing the country code as well `;
form.reset();
input.focus();
return;
}
}
接下來,我來解釋下上述代碼的一些關鍵點:
特殊邏輯說明:
Note #1: 如果你通過逗號的形式精確搜索時,如果國家簡寫不正確的化(兩個字母簡寫,比如 athens,aa),API接口不會返回任何信息。如果你輸多于三個字母的國家簡寫,而且沒有意義(比如 athens,aaaa),API接口 則會不考慮逗號的部分,則按照城市的信息默認搜索,比如直接返回希臘的雅典。
Note #2: 如果一個城市屬于多個國家,沒有進行逗號精準搜索的話,API 接口也不會把所有相關國家的城市都羅列出來,只會顯示一個城市而已。
7、最后貼上完整的 JS 代碼
'use strict';
const form=document.querySelector(".top-banner form");
const input=document.querySelector(".top-banner input");
const msg=document.querySelector(".top-banner .msg");
const list=document.querySelector(".ajax-section .cities");
const apiKey="YOUR_OWN_KEY(你申請的APIKEY)";
form.addEventListener("submit",e=>{
e.preventDefault();
let inputVal=input.value;
const listItems=list.querySelectorAll(".ajax-section .city");
const listItemsArray=Array.from(listItems);
if(listItems.length>0){
const filteredArray=listItemsArray.filter(el=>{
let content="";
if(inputVal.includes(",")){
if(inputVal.split(",")[1].length>2){
inputVal=inputVal.split(",")[0];
content=el.querySelector(".city-name span").textContent.toLocaleLowerCase();
}else{
content=el.querySelector(".city-name").dataset.name.toLowerCase();
}
} else{
content=el.querySelector(".city-name span").textContent.toLowerCase();
}
return content===inputVal.toLowerCase();
});
if(filteredArray.length>0){
msg.textContent=`Your already know the weather for
${filteredArray[0].querySelector(".city-name span").textContent}
... otherwise be more specific by providing the country code as well
`;
form.reset();
input.focus();
return;
}
}
//ajax here
const url=`https://api.openweathermap.org/data/2.5/weather?q=${inputVal}&appid=${apiKey}&units=metric`;
fetch(url)
.then(response=>response.json())
.then(data=>{
const { main,name,sys,weather } =data;
const icon=`images/${weather[0]["icon"]}.svg`;
const li=document.createElement("li");
li.classList.add("city");
const markup=`
<h2 class="city-name" data-name="${name},${sys.country}">
<span>${name}</span>
<sup>${sys.country}</sup>
</h2>
<div class="city-temp">
${Math.round(main.temp)}
<sup>°C</sup>
</div>
<figure>
<img class="city-icon" src="${icon}" alt="${weather[0]["description"]}"
<figcaption>${weather[0]["description"]}</figcaption>
</figure>
`;
li.innerHTML=markup;
list.appendChild(li);
})
.catch(()=>{
msg.textContent="please search for a valid city ";
});
msg.textContent="";
form.reset();
input.focus();
});
到這里我們的代碼終于完成了,是不是很長,希望你能看下去,建議你還是親手動手實踐一遍享受下代碼實踐的成就感,這個應用還有許多地方改需要改進,比如ajax的等待請求提示,輸入格式的驗證等等,有興趣的可以自己嘗試下。本示例大家可以點擊 擴展鏈接 進行在線體驗。
寫完這篇原創文章已是凌晨12點多,從實踐到寫文章花了將近12個小時以上,如果你喜歡我的分享,麻煩給個關注、點贊加轉發哦,你的支持,就是我分享的動力,后續會持續分享實踐案例,歡迎持續關注。
紹
天氣網(www.tianqi.com)提供各種免費的在線的天氣預報代碼,免費的天氣預報插件,方便用戶使用調用,根據ip地址自動判斷地方天氣預報。
調用方法
完整示例:
<iframe width="420" scrolling="no" height="60" frameborder="0" allowtransparency="true" src="http://i.tianqi.com/index.php?c=code&id=12&icon=1&num=5&site=12"></iframe>
實時預覽效果
使用說明
使用方式將iframe代碼放入您的網頁HTML的合適位置即可;
所有樣式示例,可查看本人博客:http://youngsforever.yicp.vip/archives/tianqiyubao
什么我們需要天氣應用程序?
功能豐富的天氣預報應用程序可以為各個行業提供巨大價值。天氣應用程序的一些值得注意的好處包括:
提供對當地天氣狀況和即將到來的天氣預報的即時訪問,從而節省您的時間。
提供有關當前和預期天氣狀況的實時通知。
幫助政府和地方政府為自然災害做準備并挽救生命。
幫助農民采取預防措施。
促進全球旅行和旅游業。
提供清晰的天氣預報,這對航空和物流業至關重要。
1、需要構建一個天氣應用程序
要成功構建天氣應用,您需要執行以下操作:
熟悉使用JavaScript(Node.js)
文本編輯器,例如記事本或IDE。我最喜歡的是Visual Studio。
訪問可靠的天氣API,例如ClimaCell
訪問地圖服務
HTML,CSS和Bootstrap知識
一旦準備好這些,就可以了。
ClimaCell Weather API概述
ClimaCell是受歡迎的天氣提供商,可通過易于使用的API 提供超準確的歷史天氣數據以及天氣預報。
它的預測功能可幫助對天氣敏感的行業中的用戶在管理其業務時保持領先。
由MicroWeather提供支持的ClimaCell API提供了可操作的天氣洞察力,該洞察力來自二十多種天氣參數。用戶還可以生成可視天氣地圖圖層,以增強他們的體驗。
建設過程
在本節中,我將向你展示如何創建一個預報應用程序,用戶可以在其中輸入名稱或名稱來輸入他們的城市或任何其他位置,并從ClimaCell API獲取天氣數據。API通過返回數據來響應請求,然后將數據顯示給用戶。
安裝NodeJS并創建一個新項目
在此項目中,我們將使用Node.js —一種最流行的JavaScript運行時環境。Node.js幫助開發人員創建快速的Web應用程序。它具有用于創建高級Web應用程序的各種庫和模塊。
如果您的設備上沒有Node.js,則可以從官方網站進行安裝。
安裝后,我們將使用此命令初始化npm-Node.js使用的默認數據包管理器。
$ npm init
這將創建我們的項目,因此將提示您輸入一些詳細信息,例如軟件包名稱,描述,Git存儲庫等。
接下來,我們安裝運行項目所需的模塊。為了生成Node.js應用程序框架,我們使用express-構建Node.js Web應用程序的框架。
$ npm install express
安裝Express框架可幫助您運行服務器,處理客戶端請求以及將正確的HTML模板與響應連接。
接下來,我們還將安裝unirest-一個簡單而強大的解決方案,允許您請求庫。
這將幫助我們向ClimaCell API發出請求并處理響應。
使用此命令:npm install unirest
至此,我們已經安裝了必要的模塊,并且項目已準備就緒。
接下來,我們使用快速生成器工具生成一個天氣應用程序。在命令行上,鍵入以下內容:express --view=pug weather-app-nodejs
你現在應該在命令行上具有如下視圖:
獲取ClimaCell Weather API
要訪問ClimaCell API,您需要在其頁面上注冊一個帳戶。
創建帳戶后,登錄其Microweather API儀表板,如下所示:
在儀表板上,單擊引用以檢查API端點。如您所見,ClimaCell API有許多端點,包括短期預報,每小時預報,實時數據等等。
值得一提的是,每個端點都有自己的代碼段。例如,這是獲取實時天氣數據的Node.js代碼片段。
你可以在開發人員資源部分中了解有關使用ClimaCell API的更多信息。
修改應用程序
要調用ClimaCell API,我們首先需要編輯一些文件。在這里,您可以使用記事本或在IDE中打開項目目錄,以便于編輯。它應顯示如下:
我們通過將bootstrap添加到layout.pug開始修改文件。打開views目錄,然后將此代碼段插入文件中。
接下來,我們通過將下面的代碼段添加到index.pug文件中來創建一個表單。
注意我們如何使用HTTP post方法將數據發送到服務器。上面的代碼還將操作參數設置為天氣路線,并將輸入的文本添加為??“ city”。
還添加了用于獲取天氣的輸入按鈕。
現在,我們在表單下方創建一個HTML表,以顯示獲取的天氣記錄。
插入上面的代碼片段將創建一個如下表:
調用ClimaCell API
要將請求發送到ClimaCell API,我們必須安裝request模塊。
npm i request --save
接下來,我們在index.js文件中添加ClimaCell API憑據。在您的路線目錄中打開文件,并添加在ClimaCell儀表板上獲得的API密鑰:
以下是添加API憑據的代碼:
添加API憑據后,我們將更新索引路由。這是通過替換index.js文件中“ /”路由中的代碼部分來完成的 。
我們首先在index.js中創建天氣路線。
此代碼段使輸入表單中的數據可以發布到索引路由。用戶輸入城市名稱后,將使用請求對象將其分配給城市變量。
然后將該URL附加城市名稱和ID,并將請求發送到ClimaCell API。
ClimaCell API服務器響應以JSON文件形式返回,然后將其解析并饋送到輸出模板。
例如,如果用戶正在尋找波士頓的天氣預報,則該應用將返回以下內容:
注-此示例中的溫度以開爾文(Kelvin)顯示,等于50°F或10°C。
添加地圖以可視化您的數據
您可以將交互式地圖集成到預測應用程序中,以增強用戶體驗。這可以通過為Web應用程序使用第三方地圖服務提供程序來實現。
Mapbox就是這樣一種工具,可幫助開發人員為其應用程序創建出色的天氣圖。它與任何天氣應用程序無縫集成。
要使用Mapbox,請在其網站上注冊并查看其API。有針對Android,iOS,Web和Unity的集成。在這種情況下,我們選擇Web集成作為我們的工具。
我們可以安裝Mapbox CDN或使用模塊捆綁器。讓我們使用模塊捆綁器。
第一步是安裝軟件包。
npm install Mapbox-gl –save
接下來,通過在<head>中包含此代碼段,將GL JS CSS文件添加到HTML文件中。
<link href='https://api.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.css' rel='stylesheet' />
現在,我們可以將地圖添加到我們的應用程序中。為此,請使用下面的代碼段。
你可以通過替換地圖來選擇放置地圖的位置
“ CONTAINER_ELEMENT_ID”。
這是使用Mapbox生成的示例地圖:
下一步是什么?
至此,很多工作已經完成,你的應用程序可以使用ClimaCell API獲取任何城市的天氣預報。
但是,你可以考慮向應用程序添加更多交互功能或擴展其功能。
你可能需要添加以下的操作:
添加搜索功能。
改善用戶界面的外觀。
通過ID或名稱查詢應用程序。
顯示目標城市及其相應ID的列表。
添加參數以顯示其他天氣數據。
集成實時通知和警告信號。
如你所見,基本的應用程序構建過程非常簡單明了。通過遵循上述過程以利用天氣API的功能,即使是初學者級的開發人員也可以在幾分鐘內啟動并運行天氣應用程序。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。