DevGang
Авторизоваться

Создание прогрессивного веб-приложения (PWA) с использованием HTML и Vanilla JavaScript

Создание прогрессивного веб-приложения (PWA) с использованием HTML и ванильного JavaScript с mp3-аудиоплеером может стать удивительным занятием.

Мы рассмотрим базовый пример того, как сервис-воркеры можно использовать для кэширования в PWA. Наше приложение представляет собой MP3-плеер, но приведенные здесь принципы применимы к любому PWA.

Manifest.json

Начнем с manifest.json:

{
  "short_name": "PWA MP3 Player",
  "name": "Progressive Web Application MP3 Player",
  "description": "An MP3 Player built as a Progressive Web Application",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#fff",
  "theme_color": "#3f51b5",
  "icons": [
    {
      "src": "icon.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}

Manifest.json предоставляет информацию о приложении (такую как название, автор, значок и описание) в текстовом файле JSON.

Цель файла manifest.json - предоставить централизованное место для размещения метаданных, связанных с веб-приложением.

Вот разбивка каждого объекта недвижимости:

  • short_name: Short_name — это более короткая версия имени приложения, которое используется на домашнем экране пользователя и везде, где место ограничено.
  • name: Полное имя приложения.
  • description: Описание приложения.
  • start_url: Это URL-адрес, с которого запустится PWA, когда пользователь запустит приложение. В этом случае он настроен на открытие домашней страницы приложения.
  • display: Свойство display определяет предпочтительный режим отображения веб-сайта разработчиком. Значение "standalone" означает, что приложение будет выглядеть и чувствовать себя как автономное приложение. Это может включать в себя приложение, имеющее другое окно, свой собственный значок в панели запуска приложений и т.д.
  • background_color: Это цвет фона приложения, который используется при отображении заставки при запуске приложения с плитки на главном экране.
  • theme_color: Определяет цвет темы по умолчанию для приложения, который влияет на цвет панели инструментов и цвет в переключателе задач.
  • icons: Это свойство представляет собой массив файлов изображений, которые можно использовать в качестве значка приложения. Каждый объект в массиве является изображением, и вы можете указать путь, размеры и тип изображения. Ключ src - это путь к файлу изображения, ключ sizes - это разделенный пробелами список размеров изображения, а ключ type - это MIME-тип для файла изображения.

Таким образом, файл manifest.json - это файл конфигурации для вашего PWA, который содержит подробную информацию о том, как должно вести себя ваше приложение при установке на устройство.

Сервис Worker

Далее, давайте настроим базового сервисного работника (sw.js):

const cacheName = 'pwa-mp3-player-v1';
const assetsToCache = [
  './',
  'index.html',
  'main.js',
  'styles.css',
  'icon.png'
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(cacheName)
      .then((cache) => {
        return cache.addAll(assetsToCache);
      })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        return response || fetch(event.request);
      })
  );
});

Когда мы говорим о прогрессивных веб-приложениях (PWA), часто появляется термин «Service Workers». Service Workers, настоящая движущая сила PWA, выполняют различные важные функции, одной из наиболее важных из которых является обработка стратегий кэширования.

Давайте разберем этот фрагмент кода JavaScript:

const cacheName = 'pwa-mp3-player-v1';

Здесь мы объявляем константу cacheName для обозначения версии нашего кеша. Версии наших кэшей — обычная практика, потому что это упрощает управление ими. Если мы обновляем какие-либо файлы в нашем проекте, мы можем изменить имя кеша, что затем заставит сервис-воркера кэшировать новые файлы.

const assetsToCache = [
  './',
  'index.html',
  'main.js',
  'styles.css',
  'icon.png'
];

В assetsToCache мы перечисляем файлы, которые хотим кэшировать. Обычно это включает в себя все статические файлы, необходимые для оболочки вашего приложения (минимальный HTML, CSS и JavaScript, необходимый для работы пользовательского интерфейса прогрессивного веб-приложения).

В части self.addEventListener происходит волшебство. Service Workers могут прослушивать несколько событий жизненного цикла. Двумя наиболее часто используемыми являются «install» и «fetch».

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(cacheName)
      .then((cache) => {
        return cache.addAll(assetsToCache);
      })
  );
});

Событие install срабатывает при первой установке сервисного работника. Здесь мы говорим сервис-воркеру открыть кэш с помощью caches.open(), а затем кэшировать все необходимые активы с помощью cache.addAll(). event.waitUntil() используется для гарантии того, что сервис-воркер не прекратит установку до тех пор, пока код внутри waitUntil не завершится.

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        return response || fetch(event.request);
      })
  );
});

После процесса установки и кэширования событие fetch срабатывает всякий раз, когда запрашивается любой ресурс (указанный в assetsToCache). Метод event.respondWith() позволяет нам перехватить запрос и предоставить ответ.

Внутри responseWith мы спрашиваем кеш, есть ли там запрошенный ресурс. Если да (caches.match(event.request) возвращает ответ, мы отвечаем кешированной версией, если нет, мы получаем ее из сети, используя fetch(event.request).

Эту стратегию часто называют Cache Falling Back to Network. Идея состоит в том, чтобы вернуть кешированный контент, когда он доступен, в противном случае вернуться к сетевому запросу.

Это может обеспечить скорость, если содержимое кэшируется, и доступность, если нет.

Большие возможности

Это только верхушка айсберга, когда речь заходит о service worker и их возможностях.

Вы можете настроить более сложные стратегии кэширования, обрабатывать почтовые запросы, фоновую синхронизацию и многое другое. service worker — это мощный инструмент в современной веб-разработке, обеспечивающий функции, подобные приложениям, в браузере.

Работает на JavaScript

Теперь давайте создадим простой аудиоплеер (main.js):

class AudioPlayer {
  constructor(audioElement) {
    this.audioElement = document.querySelector(audioElement);
  }

  play() {
    this.audioElement.play();
  }

  pause() {
    this.audioElement.pause();
  }

  togglePlay() {
    this.audioElement.paused ? this.play() : this.pause();
  }
}

document.addEventListener('DOMContentLoaded', () => {
  const player = new AudioPlayer('#audioElement');

  document.querySelector('#playButton').addEventListener('click', () => {
    player.togglePlay();
  });
});

Давайте проанализируем это и поймем, как мы можем использовать возможности объектно-ориентированного программирования на JavaScript для создания интерактивных веб-компонентов.

class AudioPlayer {
  constructor(audioElement) {
    this.audioElement = document.querySelector(audioElement);
  }

В начале мы определяем класс с именем AudioPlayer. Классы — это схема создания объектов с определенными методами и свойствами в JavaScript. Наш класс AudioPlayer принимает параметр audioElement в своем конструкторе. Этот параметр должен быть селектором аудиоэлемента HTML, которым должен управлять проигрыватель. Он использует document.querySelector для получения первого HTML-элемента, соответствующего этому селектору, и присваивает его this.audioElement.

  play() {
    this.audioElement.play();
  }

  pause() {
    this.audioElement.pause();
  }

Затем мы определяем два метода play и pause внутри класса. Эти методы, при вызове, используют встроенные методы play и pause в HTMLAudioElement для управления воспроизведением.

  togglePlay() {
    this.audioElement.paused ? this.play() : this.pause();
  }
}

Далее у нас есть метод togglePlay. Это проверяет, приостановлен ли звук в данный момент (свойство paused имеет значение true, когда звук не воспроизводится). Если он приостановлен, он вызывает метод play, а если он воспроизводится, он вызывает метод pause. Это простой способ переключаться между воспроизведением и паузой с помощью одной функции.

document.addEventListener('DOMContentLoaded', () => {
  const player = new AudioPlayer('#audioElement');

  document.querySelector('#playButton').addEventListener('click', () => {
    player.togglePlay();
  });
});

Наконец, вне класса у нас есть код, который использует наш AudioPlayer. Во-первых, мы ждем события DOMContentLoaded, чтобы убедиться, что наш HTML полностью загружен, прежде чем мы попытаемся взаимодействовать с ним.

Затем мы создаем новый экземпляр нашего класса AudioPlayer, передавая селектор для нашего аудиоэлемента.

Мы также добавляем прослушиватель событий к кнопке воспроизведения (#playButton). Когда кнопка нажата, метод togglePlay вызывается для нашего экземпляра аудиоплеера.

Это позволяет нам запускать или приостанавливать воспроизведение звука, нажав кнопку.

Передовая практика

Этот пример является прекрасной иллюстрацией того, как мы можем создавать повторно используемый, организованный код в JavaScript, используя классы. Класс AudioPlayer абстрагируется от деталей того, как воспроизводить, приостанавливать и переключать звук, предоставляя простой в использовании интерфейс, который мы можем использовать в нашем приложении.

Это позволяет нам сделать наш код более модульным, ремонтопригодным и управляемым.

Важная заметка

Пожалуйста, обратите внимание, что service workers и Cache API работают только по протоколу HTTPS или localhost по соображениям безопасности. Если вы разрабатываете локально, это должно сработать, но как только вы будете готовы к развертыванию, вам нужно будет убедиться, что ваш сервер использует HTTPS.

HTML загружает все

Вот базовый файл index.html, который работает с предоставленным вами кодом JavaScript:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PWA MP3 Player</title>
    <link rel="manifest" href="manifest.json">
    <style>
        /* Add your CSS styles here */
    </style>
</head>
<body>
    <div class="player">
        <audio id="audioElement" src="song.mp3" controls></audio>
        <button id="playButton">Play/Pause</button>
    </div>

    <script src="main.js"></script>
    <script>
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', function() {
                navigator.serviceWorker.register('/sw.js').then(function(registration) {
                    console.log('ServiceWorker registration successful with scope: ', registration.scope);
                }, function(err) {
                    console.log('ServiceWorker registration failed: ', err);
                });
            });
        }
    </script>
</body>
</html>

В этом HTML-файле:

  • У нас есть тег <audio> с id="audioElement". Это аудиоплеер, которым будет управлять класс AudioPlayer. Атрибут src должен быть путем к вашему mp3 файлу.
  • У нас есть <button> с id="playButton". Когда эта кнопка нажата, она вызывает метод togglePlay для экземпляра AudioPlayer, запуская или приостанавливая воспроизведение звука.
  • Мы включаем файл main.js, содержащий класс AudioPlayer.
  • У нас также есть скрипт для регистрации нашего service worker (sw.js), если браузер его поддерживает. Сервисный работник будет контролировать сетевые запросы, чтобы обеспечить бесперебойную работу в автономном режиме.

Занимаясь разработкой приложений, вы часто сталкиваетесь с такой задачей, как увеличить границы использования вашего приложения. Предлагаем вам изучить статью об использовании нескольких языков в вашем приложении. Тем самым вы увеличите возможности расширения вашего приложения и это может быть выгодно пользователю. Спасибо за внимание.

Источник:

#JavaScript #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу