• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用 Vanilla JavaScript 构建一个简单的天气应用程序

在今天的教程中,我们将学习如何使用 Vanilla javascript 构建一个简单但功能齐全的天气应用程序

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第1张

你将要创造什么

我们有很多有趣的事情要讲,所以喝杯咖啡,让我们开始吧!这是为您准备的快速导航菜单。

您将在此 JavaScript 天气 api 教程中学到什么:

  1. 搭建天气应用程序

    1. 查找天气 API

    2. 什么是开放天气?

    3. 在哪里可以找到天气图标和天气 UI 工具包

  2. 定义页面标记

  3. 指定一些基本样式

  4. 设置主要样式

  5. 添加 javaScript

  6. 奖励:使用 weatherstack API 获取实时天气数据

这是CodePen 上的演示,供您分叉和使用:

See the Pen  Simple Weather App By Using OpenWeatherMap API & Custom Icons by Envato Tuts+ (@tutsplus)  on CodePen.

本教程假设您熟悉 ajax,这是一种基本的前端技术。如果您刚刚开始,请查看此系列。

1.搭建天气应用程序

在开始创建我们的应用程序之前,我们必须考虑一些事项。

查找天气 API

首先,我们必须找到一个提供商,让我们将其天气数据整合到我们的应用程序中。幸运的是,有几个 不同的供应商可以开发天气应用程序。其中大多数包括免费套餐以及根据服务/功能扩展的高级订阅。 

什么是开放天气?

在我们的例子中,我们将使用 OpenWeatherMap,这是最受欢迎的免费选择之一。OpenWeather 将自己描述为自 2014 年以来从事深入天气数据科学的 IT 专家和数据科学家团队。对于地球上的每个点,OpenWeather 通过光速 API 提供可靠的历史、当前和预测天气数据。  

要利用其功能,首先,我们必须注册一个 API 密钥:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第2张

该服务附带不同的套餐。从下面的可视化中可以看出,启动器(免费)允许每分钟 60 个呼叫,这符合我们的需求:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第3张

因此,在继续之前,请确保您已注册 API 密钥。稍后,我们将在脚本中包含该键。 

请记住,测试应用程序的最佳方法是分叉 CodePen 演示并包含您自己的密钥。如果我们都共享相同的密钥,则应用程序可能由于 API 调用限制而无法运行。

在哪里可以找到天气图标和天气 UI 工具包 

在开始使用天气 API JavaScript 代码之前,我们需要天气应用程序图标。值得注意的是,OpenWeatherMap 带有自己的图标集,我们将看看这些。但是,我们将更进一步并使用一些自定义的。 

现在,如果您是网页设计师或从事多个网页设计项目,Envato Elements 是您的最佳选择。

这个基于订阅的市场以较低的月费,让您可以无限制地访问您的项目所需的一切。

在这里,我们将回顾一些顶级天气图标矢量集和天气 UI 套件。继续浏览 Envato Elements天气 UI 工具包库以获取更多信息!

1.天气图标和字体

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第4张

如果您喜欢简单的天气应用程序图标,这些是给您的。这个天气图标矢量集带有 32 个矢量图标和一个预测字体。这个完整的天气图标矢量集包括 32 个 svg 文件以及 htmlcss 参考。

2. UICON 天气图标

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第5张


这个天气图标矢量集具有现代和清新的外观。有两种颜色版本的 12 个天气应用程序图标。所有天气图标均采用 EPS 制作,设计简约。

3.矢量天气图标和字体

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第6张


如果您正在寻找完整的天气图标矢量集,请查看此。天气应用程序图标包带有 42 个独特的图标和一种字体。天气图标有 AI、psd 和 SVG 格式。

4.天气应用模板

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第7张


现在,如果您想使用模板构建天气应用程序,我们有这个天气 UI 工具包。您可以在 photoshopillustratoradobe XD 中使用此模板编辑您自己的天气应用程序。

5.适用于 Web 或移动设备的天气小部件

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第8张

如果您想构建不同的天气应用程序,这是另一个很酷的天气 UI 工具包。这个天气 UI 套件具有简洁的设计。您可以使用 sketch 对其进行编辑。

2.定义页面标记

现在我们已经看到了一些顶级天气应用程序图标,是时候使用 JavaScript 构建一个天气网站了。我们将定义两个部分。 

第一部分将包括一个标题、一个搜索表单和一个空span元素。在某些条件下,此元素将通过适当的消息变得可见。具体来说,如果没有任何可用于请求的城市的天气数据,或者该城市的数据是已知的。 

第二部分将包括城市列表。默认情况下,它不包含任何城市。但是,当我们开始搜索特定城市的天气时,如果天气数据可用,则会将相应的列表项(城市)附加到无序列表中。

这是初始页面标记:

<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>

注意:在我们的 CodePen 演示autofocus中,搜索字段的属性将不起作用。事实上,如果你打开浏览器控制台,它会抛出以下错误:


使用 Vanilla JavaScript 构建一个简单的天气应用程序  第9张


但是,如果您在本地运行此应用程序(而不是作为 CodePen 项目),则不会存在此问题。

这是与我们将通过 JavaScript 动态生成的列表项关联的标记:

<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>

3.指定一些基本样式

准备好天气应用程序的标记后,我们将继续使用 CSS。与往常一样,第一步是指定一些 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;

}

4.设置主要样式

现在让我们讨论一下我们的天气应用程序的主要样式。

第 1 节样式

首先,我们将在第一部分的元素中添加一些简单的样式。 

在中等屏幕及以上 (>700px) 上,布局应如下所示:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第10张

在较小的屏幕上,表单元素将分成两行:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第11张

以下是相关的样式:

/*CUSTOM VARIABLES HERE*/

 

.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 节样式

我们将使用 CSS Grid 来布置列表项。请记住,每个列表项将代表一个城市。它们的宽度将取决于屏幕尺寸。

在大屏幕(>1000px)上,我们将有一个四列布局。

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第12张

然后在中型屏幕(>700px 和 ≤1000px)上采用三列布局,在小屏幕(>500px 和≤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伪元素添加。 

在卡片内,我们将放置有关所请求城市的天气信息。这些将来自我们的请求,除了图标。如上所述,这些图标是从 Envato Elements 中获取的,它们将显示该城市的当前天气状况并匹配等效的 OpenWeatherMap 图标。


使用 Vanilla JavaScript 构建一个简单的天气应用程序  第13张


您可以在下面看到此布局所需的部分 CSS:

/*CUSTOM VARIABLES HERE*/

 

.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;

}

5.添加JavaScript

此时,我们已准备好构建天气应用程序的核心功能。我们开始做吧!

提交表格

每次用户通过按Enter键或Submit按钮提交表单时,我们将做两件事:

  1. 停止提交表单,从而防止重新加载页面。

  2. 抓取包含在搜索字段中的值。

这是起始代码:

const form = document.queryselector(".top-banner form");

 

form.addeventListener("submit", e => {

  e.preventDefault();

  const inputVal = input.value;

});

接下来,我们将检查第二部分中是否有列表项(城市)。 

执行 AJAX 请求

我们将从列表为空的假设开始。也就是说,它过去从未运行过任何 AJAX 请求。在这种情况下,我们将向 OpenWeatherMap API 执行请求并传递以下参数:

  1. 城市名称(例如 athens)或逗号分隔的城市名称以及***代码(例如 athens,gr),这将是搜索字段的值

  2. API 密钥。同样,您应该使用 自己的密钥 来避免由于 API 调用限制而导致的意外错误。

  3. 请求城市的温度单位。在我们的例子中,我们将选择 Celcius。

考虑到以上所有内容,按照 API 文档,我们的请求 URL 应该如下所示:

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`;

要执行 AJAX 请求,我们有很多选择。我们可以使用普通的旧XMLHttpRequest API、更新的fetch API,甚至是像jquery和Axios这样的 JavaScript 库。对于此示例,我们将使用 Fetch API。 

要获取所需的数据,我们必须执行以下操作:

  • 将我们要访问的 URL 传递给该fetch()方法。 

  • 此方法将返回一个包含响应(一个Response对象)的 Promise。但这不是实际的响应,只是一个 HTTP 响应。要获取所需 JSON 格式的响应数据(这是 OpenWeatherMap 的默认数据格式),我们将使用 Response 对象的 json()方法。

  • 此方法将返回另一个 Promise。完成后,数据将可用于操作。

  • 如果由于某种原因请求不成功,屏幕上会出现相应的消息。

所以,我们的 AJAX 请求看起来像这样:

...

 

 fetch(url)

  .then(response => response.json())

  .then(data => {

    // do stuff with the data

  })

  .catch(() => {

    msg.textContent = "Please search for a valid city ?";

  });

提示:我们可以 对 AJAX 请求then()使用更新且更易读的方法,而不是链接s。async/await

以下是响应数据的示例:


使用 Vanilla JavaScript 构建一个简单的天气应用程序  第14张


构建列表项组件

有了 AJAX 请求,每次我们在搜索字段中输入城市时,API 都会返回其天气数据(如果可用)。我们现在的工作是只收集我们需要的数据,然后创建关联的列表项,最后将其附加到无序列表中。

这是负责这项工作的代码:

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);

这里有两点我们需要讨论:

  1. 如果您再次查看上面的响应可视化,您会注意到 API 返回一个icon代码(例如“50d”),其中包含目标城市的当前天气状况。基于此代码,我们能够构建图标 URL 并通过img标签将其显示在卡片中。

  2. 在.city-name每个列表项的元素中,我们将附加data-name带有值的属性cityName,countryCode(例如madrid,es)。稍后我们将使用此值来防止重复请求。

重置事物

最后,在 AJAX 请求之后,我们将清除.msg元素的内容、搜索字段的值,并将焦点也放在该字段上:

...

 

msg.textContent = "";

form.reset();

input.focus();

干得好,伙计们!我们刚刚创建了我们应用程序的第一个版本。当您输入自己的 API 密钥并搜索城市时,您应该会看到与该布局类似的卡片布局:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第15张

添加自定义天气图标

现在让我们稍微自定义一下我们应用程序的外观和感觉。我们将用我们之前从 Envato Elements 下载的 SVG 替换默认的 OpenWeatherMap PNG 图标。

为此,我已将所有新图标上传到 CodePen(通过资产管理器,因为我是 PRO 成员)并更改了它们的名称,因此它们将匹配原始图标的名称和天气状况,如下所示:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第16张

然后,在代码中,我们只需要更改图标路径:

//BEFORE

const icon = `https://openweathermap.org/img/wn/${

  weather[0]["icon"]

}@2x.png`;

 

//AFTER

const icon = `https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/${

  weather[0]["icon"]

}.svg`;

防止重复请求

我们还有一件事需要解决。到目前为止,当我们成功执行 AJAX 请求时,就会创建一个列表项。也就是说,列表可以包含多个相同的列表项,它们指向同一个城市,如下所示:


使用 Vanilla JavaScript 构建一个简单的天气应用程序  第17张

那是糟糕的用户体验,所以让我们确保只为特定城市触发一个请求。 

但在此之前,还有一件事需要考虑。同一个城市名称可以存在于多个***。例如,如果我们在 OpenWeatherMap 的搜索器中搜索“雅典” ,我们将看到以下结果:

使用 Vanilla JavaScript 构建一个简单的天气应用程序  第18张

考虑到以上所有内容,我们将编写一些代码来确保每个城市、每个***只执行一个请求:

...

 

//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;

  }

}

让我解释一下这里发生了什么动作:

  1. 再次在提交处理程序期间,在发出 AJAX 请求之前,我们检查无序列表是否为空。如果它不为空,则表示至少已经执行了一个成功的 AJAX 请求。 

  2. 接下来,我们检查是否有一个列表项的城市名称或其data-name属性的值等于搜索字段的值。

  3. 如果是这样,则意味着用户已经知道该城市的天气,因此无需执行另一个 AJAX 请求。作为以下动作,我们将向他们显示相关消息,清除搜索字段的值并赋予其焦点。

注意#1:正如我所注意到的,如果您搜索一个最多包含两个字母且不代表任何***/地区代码的城市(例如 athens,aa),API 将不会返回任何内容。另一方面,如果您搜索一个城市以及至少三个不代表任何***/地区代码的字母(例如 athens、aaaa),API 将忽略逗号后面的部分并返回所有命名为第一部分(例如雅典)。

注意#2: 在本练习中,我们不会涵盖一个***包含多个同名城市的特殊情况(例如美国的雅典)。因此,例如,如果用户搜索“athens,us”,屏幕上只会出现一个城市,而不是更多。为了涵盖理想的场景,用户应该以某种方式知道城市 ID(例如,可能将它们作为下拉菜单提供)并根据它进行搜索,而不是根据其名称进行搜索。

干得好,伙计们!我们刚刚构建了我们的应用程序。让我们来看看:

See the Pen  Simple Weather App By Using OpenWeatherMap API & Custom Icons by Envato Tuts+ (@tutsplus)  on CodePen.

您的天气应用程序已准备就绪!

我们完成了!这确实是一段漫长的旅程,但我希望你喜欢它,并且它有助于提高你的前端技能。

再一次,不要忘记将您自己的密钥用于实时应用程序测试! 

一如既往,非常感谢您的阅读!


文章目录
  • 您将在此 JavaScript 天气 api 教程中学到什么:
  • 这是CodePen 上的演示,供您分叉和使用:
  • 1.搭建天气应用程序
    • 查找天气 API
    • 什么是开放天气?
  • 在哪里可以找到天气图标和天气 UI 工具包
    • 1.天气图标和字体
    • 2. UICON 天气图标
    • 3.矢量天气图标和字体
    • 4.天气应用模板
    • 5.适用于 Web 或移动设备的天气小部件
  • 2.定义页面标记
  • 3.指定一些基本样式
  • 4.设置主要样式
    • 第 1 节样式
  • 第 2 节样式
  • 5.添加JavaScript
    • 提交表格
    • 执行 AJAX 请求
    • 构建列表项组件
    • 重置事物
    • 添加自定义天气图标
    • 防止重复请求
  • 您的天气应用程序已准备就绪!