EP01 | 跟著影片做前端練習 - Build a Weather App & Get User's Location

sLocation

練習影片

練習重點

串接 API

架構

HTML & CSS

內容繁複,請參考codepen

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
(function () {
startLoading()
// flip
let card = document.querySelector('.card')
let cardFront = document.querySelector('.card_front')
let cardBack = document.querySelector('.card_back')
let search = document.querySelector('.search')
card.addEventListener('click', flip)

function flip(e) {
const target = e.target
if (target.parentElement.matches('.detailIcon') || target.parentElement.matches('.backIcon')) {
cardFront.classList.toggle('hidden')
cardBack.classList.toggle('hidden')
search.classList.toggle('front')
search.classList.toggle('back')
}
}
//串接API
const week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
let lat = ''
let lng = ''
// 找出目前地點經緯度後得出地點及天氣
function getUserLoaction() {
navigator.geolocation.getCurrentPosition((data) => {
lat = data.coords.latitude
lng = data.coords.longitude
getUserLoactionName(lat, lng)
getWeather(lat, lng)
}, console.error)
}
// 經緯度的天氣
function getWeather(lat, lon) {
const weatherApiKey = 'c41f7e1b3970ad769ca21a063172356b'
const weatherApi = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&exclude=hourly,minutely,alerts&units=metric&appid=${weatherApiKey}`
fetch(weatherApi).then(res => {
return res.json()
}).then(data => {
const {
current,
daily
} = data
document.querySelector('.today-text').innerHTML = `${week[new Date(current.dt * 1000).getDay()]}<br> ${new Date(current.dt * 1000).getDate()} / ${new Date(current.dt).getDay()} , ${new Date(current.dt * 1000).getFullYear()}`
document.querySelector('.precipitation').textContent = `${Math.round(daily[0].pop * 100)} %`
document.querySelector('.feel').innerHTML = `${current.feels_like}<sup>°C</sup>`
document.querySelector('.today-temperature>span>span').textContent = `${current.temp}`
document.querySelector('.today-temperature-icon').src = `http://openweathermap.org/img/wn/${current.weather[0].icon}@2x.png`

let futureList = ''
for (let i = 1; i < 4; i++) {
futureList += `<li class="flexRowCenter futureList">
<span>${week[new Date(daily[i].dt * 1000).getDay()]}</span>
<span class="future_description flexRowCenter">
<span class="future_temperature flexRowCenter">
<img src="http://openweathermap.org/img/wn/${daily[i].weather[0].icon}.png" style="width:40px">
<span>${daily[i].temp.min}<sup>°C</sup></span>
</span>
<span class="future_precipitation flexRowCenter">
<i class="fas fa-umbrella"></i>
<span>${Math.round(daily[i].pop * 100)}%</span>
</span>
</span>
</li>`
}
document.querySelector('.future>ul').innerHTML = futureList
//back
document.querySelector('.temperature').innerHTML = `${daily[0].temp.min}<sup>°C</sup> / ${daily[0].temp.max}<sup>°C</sup>`
document.querySelector('.humidity').textContent = `${current.humidity} %`
document.querySelector('.dewPoint').textContent = `${current.dew_point}`
document.querySelector('.windSpeed').previousElementSibling.style.transform = `rotate(${current.wind_deg - 45}deg)`
document.querySelector('.windSpeed').textContent = `${current.wind_speed} m/s`
document.querySelector('.pressure').textContent = `${current.pressure} hpa`
document.querySelector('.visibility').textContent = `${current.visibility / 1000} km`
document.querySelector('.sunrise').textContent = `${new Date(current.sunrise * 1000).getHours()} : ${new Date(current.sunrise * 1000).getMinutes()}`
document.querySelector('.sunset').textContent = `${new Date(current.sunset * 1000).getHours()} : ${new Date(current.sunset * 1000).getMinutes()}`
endLoading()
}).catch(err => console.log(err))
}
// openCage Api
const openCageApiKey = '1a526c9f50a348c4920aa569300ff5a5'
// 地點搜尋經緯度
function getSearchLocation(e) {
const locationName = document.querySelector('.searchLocation').value
if (e.target.parentElement.matches('.searchIcon')) {
startLoading()
const openCageApi = `https://api.opencagedata.com/geocode/v1/json?q=${locationName}&key=${openCageApiKey}&lang=zh_tw&pretty=1`
fetch(openCageApi).then(res => {
return res.json()
}).then(data => {
console.log(data)
document.querySelector('.userLocation').textContent = `${data.results[0].formatted}`
let {
lat,
lng
} = data.results[0].geometry
getWeather(lat, lng)
}).catch(err => console.log(err))

}
}
//經緯度的地址
function getUserLoactionName(lat, lon) {
const openCageApi = `https://api.opencagedata.com/geocode/v1/json?q=${lat}+${lon}&key=${openCageApiKey}&lang=zh_tw&pretty=1`
fetch(openCageApi).then(res => {
return res.json()
}).then(data => {
document.querySelector('.userLocation').textContent = `${data.results[0].formatted}`
const {
components
} = data.results[0]
getBackground([components['country_code']].join(','))
}).catch(err => console.log(err))
}
// 背景圖片
function getBackground(nation) {
const unsplashApi = `https://source.unsplash.com/1600x900/?landscape,${nation}`
document.querySelector('.wrap').style.backgroundImage = `url(${unsplashApi})`
}
// 載入
function startLoading(){
document.querySelector('.loading').style.display = 'flex'
}
function endLoading(){
document.querySelector('.loading').style.display = 'none'
}

//執行
getUserLoaction()
//search 表單綁定監聽器
search.addEventListener('click', getSearchLocation)
})()

心得記錄

覺得最困難的是尋找正確的 API 資料,並從 API 資料中取得自己所需要的,之後要練習把程式碼寫得更漂亮一些。

Demo:

See the Pen EP01 | 跟著影片做前端練習 - Build a Weather App & Get User's Location by Celeste6666 (@celeste6666) on CodePen.