外部の情報を取得し天気情報を表示するWebアプリケーションを作ります。
キーワード:オブジェクト, WebAPI, 非同期処理
作成例(完成イメージ)
- 作成例:https://ngsm-syr.github.io/javascript_weather/
- コード:https://github.com/ngsm-syr/javascript_weather/
下記の順番で進めます。
- HTMLで基本の文書構造を作る
- CSSでUIを整える
- JavaScriptでWebAPIを使って情報を取得
- 画面に情報を表示
- 天気コードを日本語とアイコンに変換
【準備】フォルダ:javascript_weather
①JavaScriptを書くための準備で作成したフォルダ(空のHTML、CSS、JavaScriptが入っている)を準備します。GitHubからもダウンロードできます。
②フォルダの名前を「javascript_weather」に変更します
③Visual Studio Codeに、拡張機能 Live Server をインストールします(未実施の方)
※外部ファイル(JSONファイルやAPIなど)を読み込むときは、ローカルサーバーで動作確認をします
HTMLの準備
まず、コンテンツ部分を用意します。どの場所の天気を表示させるかは任意です。●●のところは自分で設定してください。
▼index.html
<header>
<h1>今日の天気</h1>
</header>
<main>
<div class="container">
<h2>●●の天気</h2>
<div id="weather-result">
<div id="weather-icon">?</div>
<p id="weather-text">ボタンを押して取得</p>
<p id="temperature">--℃</p>
</div>
<button id="get-weather-btn">天気を更新</button>
</div>
</main>
▼style.css
body {
font-family: sans-serif;
text-align: center;
background-color: #e0f7fa;
padding: 50px;
}
.container {
background: white;
max-width: 300px;
margin: 0 auto;
padding: 20px;
border-radius: 15px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
#weather-icon {
font-size: 5rem;
margin: 10px 0;
}
#temperature {
font-size: 2em;
font-weight: bold;
color: #00796b;
margin: 10px 0;
}
button {
padding: 10px 20px;
font-size: 1em;
cursor: pointer;
background-color: #00acc1;
color: white;
border: none;
border-radius: 5px;
}
button:hover {
background-color: #00838f;
}
WebAPIを読み込む
今回はオープンソースの Open-Meteoを使います(商用利用は有料)。Open-MeteoではURLのパラメーターに各種設定を入れることで、情報取得する仕組みになっています。今回は、緯度と経度を指定し「現在の天気」を取得する設定にしています。緯度と経度は任意の値を設定します。GoogleMapなどで確認できます。Open-Meteoのサイトにも都市名で検索できる機能があります。
▼script.js
// 緯度・経度
const latitude = xxxxxxxxxxxx;
const longitude = xxxxxxxxxxxx;
// Open-MeteoのAPI URL
const apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t_weather=true`;
// 要素の取得
const btn = document.getElementById('get-weather-btn');
// 天気情報を取得する関数
async function fetchWeather() {
console.log('天気情報を取得中...');
// APIからデータを取得
const response = await fetch(apiUrl);
const data = await response.json();
// コンソールでデータを確認
console.log('取得したデータ:', data);
console.log('現在の天気情報:', data.current_weather);
console.log('気温:', data.current_weather.temperature);
console.log('天気コード:', data.current_weather.weathercode);
}
// ボタンをクリックしたら実行
btn.addEventListener('click', fetchWeather);
ボタンをクリックするとコンソールに取得した情報が表示されます。オブジェクトとして情報が取得されていることが確認できます。
【参考】async / await
asyncは「非同期」の関数を書く方法です。非同期とは、複数のものがタイミングを合わせずに処理を行うことで、ある処理を実行中に、他の処理をすることが可能です。ネットワークで情報を取得するときなどに使います。
通常、JavaScriptは同期処理されていて、順番に処理を行います。もし同期処理だとするとAPIの情報を取得している間、処理が止まってしまい、ブラウザが固まってしまう可能性もあります。非同期処理することで、他の動作に影響させずに、読み込み処理を行うことができます。
ここでは、fetch(apiUrl)が非同期処理として行われ、awaitによって、処理が完了するまで待機する形になっています(fetch()は外部情報などを取得する関数です)。
続く、response.json()によって、jsonテキストを、JavaScriptオブジェクトに変換しています。
【参考】オブジェクト
変数を管理する入れ物。1つの「モノ」に関する情報を、ひとまとめにしたデータのことです。{ } で囲まれた部分をオブジェクトリテラルと呼び、1つ分のオブジェクトを指します。
{ latitude: xxxxx, longitude: xxxxx, timezone: "GMT", ......... }
HTMLの各要素を取得(定数の定義)
天気の情報を画面上に表示するため、ボタン以外の要素を取得します。ボタンは前の工程ですでに要素を取得しています。
▼script.js
// 要素の取得
const btn = document.getElementById('get-weather-btn');
const iconElem = document.getElementById('weather-icon');
const textElem = document.getElementById('weather-text');
const tempElem = document.getElementById('temperature');
オブジェクトの情報を表示する
console.logで確認したデータを、実際に画面上に表示します。
▼script.js(console.logの記述の下に追記)
// コンソールでデータを確認
console.log('取得したデータ:', data);
console.log('現在の天気情報:', data.current_weather);
console.log('気温:', data.current_weather.temperature);
console.log('天気コード:', data.current_weather.weathercode);
// データの取り出し
const current = data.current_weather;
const temp = current.temperature; // 気温
const code = current.weathercode; // 天気コード
// 画面に表示
iconElem.textContent = 'アイコン';
textElem.textContent = `天気コード: ${code}`;
tempElem.textContent = `${temp}℃`;
【参考】テンプレートリテラル
テンプレートリテラルを使うと、変数の値を文字列に挿入することができます。
「``内で変数を${ } で囲う」ことで使用できます。記号` は、バッククォート(逆引用符)です。
天気コードを変換する
前の工程で確認したように、Open-Meteoでは天気の情報を天気コード(weathercode)として返してきます。これはWMO(世界気象機関)の国際的な気象コードを使用しています。そのため「晴れ」や「曇り」などの日本語、あるいは天気アイコンなどを表示させるには、変換作業が必要です。
- 参考:気象関係コード表(日本海洋データセンターより)
以下の例では、晴れ、曇り、雨など代表的な天気のみ設定しています。雷雨、雪など他の天気にも対応するには、それぞれ対応する情報を準備しておきます。
▼script.js(ボタンの取得のあと、関数より前)
// ボタンの取得
// 天気コードの変換
const weatherCodes = {
0: '快晴',
1: '晴れ',
2: '一部曇り',
3: '曇り',
61: '小雨',
63: '雨',
65: '大雨',
};
// 天気情報を取得する関数
async function fetchWeather() {
//中略
// 登録がないコードは「不明」とする
const weatherInfo = weatherCodes[code] || '不明';
// 画面に表示
iconElem.textContent = 'アイコン';
textElem.textContent = weatherInfo;
tempElem.textContent = `${temp}℃`;
}
【参考】論理和演算子(||)
x || y
x が true に変換できる場合は x を返し、それ以外の場合は y を返します。ここでは、weatherCodes[code]が存在しない場合、に右側の'不明'を返します。
weatherCodes[code]は、オブジェクトのプロパティを変数や文字列で参照する方法です。
const weatherCodes = { 0: '快晴', 1: '晴れ', 2: '一部曇り' };
const code = 1;
const text = weatherCodes[code]; // '晴れ'
アイコンを表示する
テキストだけでなく天気アイコンも表示されるようにします。オブジェクトを使って、テキストとアイコンの情報を1つにまとめます。
▼script.js
// 天気コードの変換
const weatherCodes = {
0: { text: '快晴', icon: '☀️' },
1: { text: '晴れ', icon: '🌤️' },
2: { text: '一部曇り', icon: '⛅' },
3: { text: '曇り', icon: '☁️' },
61: { text: '小雨', icon: '🌧️' },
63: { text: '雨', icon: '🌧️' },
65: { text: '大雨', icon: '🌧️' },
};
// 天気情報を取得する関数
async function fetchWeather() {
//中略
// 登録がないコードは「不明」とする
const weatherInfo = weatherCodes[code] || { text: '不明', icon: '?' };
// 画面に表示
iconElem.textContent = weatherInfo.icon;
textElem.textContent = weatherInfo.text;
tempElem.textContent = `${temp}℃`;
}
【応用】カスタマイズ例:アイコンの代わりに画像ファイルを表示する
アイコンの代わりに画像を表示させたい場合はHTMLでimg要素を挿入しておき、オブジェクトの情報でsrcとaltを変更します。
▼index.html
<img id="weather-icon" src="" alt="天気アイコン">
▼style.css
#weather-icon {
width: 100px;
height: 100px;
object-fit: contain;
}
▼script.js(一部のみ掲載)
const weatherCodes = {
0: { text: '快晴', image: 'images/sunny.png' },
......
}
async function fetchWeather() {
//読み込み中の表示
iconElem.src = 'images/loading.png';
......
// 画面に表示
iconElem.src = weatherInfo.image;
iconElem.alt = weatherInfo.text;
......
参考書籍・リンク
- 「独習JavaScript」CodeMafia 外村将大, 翔泳社, 2021
- https://developer.mozilla.org/ja/docs/Glossary/Asynchronous
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
- https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch
- https://developer.mozilla.org/ja/docs/Web/API/Window/fetch
- https://developer.mozilla.org/ja/docs/Learn_web_development/Core/Scripting/JSON
- https://developer.mozilla.org/ja/docs/Web/API/Response/json
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR