12 редко используемых веб-API для вашего сайта

javascript logo

Хочешь проверить свои знания по JS?

Подпишись на наш канал с тестами по JS в Telegram!

Решать задачи

×

Веб-API около сотни, а вы используете лишь 5% из них. Давайте запускать в ход остальные 95%!

12 редко используемых веб-API для вашего сайта
Photo by Studio Republic on Unsplash

Нырнув в темные глубины спецификаций, я понял, что многие технологии остаются незамеченными. Цель этой статьи — вытащить их на свет божий. Я на практических примерах покажу, что многие API действительно стоит попробовать!

Каждый раздел этой статьи будет посвящен отдельному API и снабжен примером, демонстрирующим практический юзкейс.

От редакции Techrocks: о том, что такое API, можно почитать в статьях:

Вертикальный режим

12 редко используемых веб-API для вашего сайта
Экран слишком узкий. Попробуйте открыть в горизонтальном режиме.

Некоторые приложения, например, нелинейные видеоредакторы, не предназначены для вертикальных устройств. Они попросту не работают должным образом на вертикальных экранах!

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

Не было бы лучше просто предупреждать пользователей, что их экран неправильно повернут? Позвольте представить вам Screen Orientation API!

Во избежание ошибок важно проверять поддержку Screen Orientation API. Это просто: if ('orientation' in screen). Этот паттерн вы увидите в моей статье неоднократно.

The Screen Orientation API

Браузеры предоставляют глобальную переменную с именем screen, которую мы будем использовать для доступа к необходимой нам информации. Доступ к экземпляру [ScreenOrientation](https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation) можно получить с помощью screen.orientation. Мы будем работать с этим объектом на протяжении всего этого раздела.

Определение ориентации экрана

12 редко используемых веб-API для вашего сайта

Типы ориентации экрана и углы: https://w3c.github.io/screen-orientation/#dfn-screen-orientation-values-table

Вопреки распространенному мнению, экран может быть повернут в четырех направлениях, как показано на картинке. Но нас интересует только то, в вертикальном он положении или в горизонтальном. Функцию, которая будет это проверять, написать довольно просто:

function getOrientation() {  
    const isPortrait = screen.orientation.type.startswith('portrait')  
    return isPortrait ? 'portrait' : 'landscape'
}

Блокировка ориентации экрана

Нативные приложения типа Instagram блокируют ориентацию, пока пользователь использует приложение. Поскольку граница между PWA и нативными приложениями становится все более размытой, не удивительно, что эта функция есть и в вебе.

Мы можем блокировать и разблокировать ориентацию экрана при помощи следующего кода (только обратите внимание на поддержку браузерами):

screen.orientation.lock(orientation)

Не забудьте также обработать ошибки, потому что, как я уже намекнул, эта фича не слишком хорошо поддерживается.

Полноэкранный режим для вашего сайта

See the Pen
Fullscreen API
by Ludvig Lindblom (@ludviglindblom)
on CodePen.

Браузеры показывают пользователю различные элементы UI, отвлекая от главного.

12 редко используемых веб-API для вашего сайта

Это приобретает большое значение, когда речь идет о контенте с эффектом присутствия:

  • фильмы
  • игры
  • полноразмерные изображения
  • и так далее.

К счастью, у нас есть Fullscreen API!

Вход в полноэкранный режим

Удивительно, но в полноэкранный режим может переходить любой элемент DOM:

el.requestFullscreen()

Тем не менее, чаще всего мы хотим, чтобы на полный экран раскрылась вся страница. Доступ к корневому элементу документа — <html> — в JavaScript можно получить при помощи document.documentElement.

Так что следующий сниппет можно увидеть в вебе тут и там:

document.documentElement.requestFullscreen()

Выход из полноэкранного режима

Выходить можно по-разному. Например, использовать дефолтные методы браузера: клавиши ESC и F11.

Также можно выйти путем переключения вкладок Ctrl+Tab или окон Alt+Tab.

Но самый важный механизм выхода тот, который дадите вы — разработчик. Вы можете запрограммировать выход из полноэкранного режима при помощи следующего кода:

document.exitFullscreen()

Во избежание ошибок проверяйте наличие этой функции перед ее вызовом:

if (document.exitFullscreen) {    
    document.exitFullscreen()
}

Проверка того, находится ли пользователь в полноэкранном режиме

Предположим, мы хотим реализовать такой переключатель для полноэкранного режима, какой видели в начале раздела в Codepen. Для этого нам нужна возможность проверить, активен ли полноэкранный режим.

Такую проверку можно сделать следующим образом:

document.fullscreenElement // returns 'null' or the fullscreen-enabled DOM element

Для лучшей браузерной поддержки нужно проверить несколько атрибутов:

document.fullscreenElement    
    || document.mozFullscreenElement    
    || document.msFullscreenElement    
    || document.webkitFullscreenElement

Теперь можно реализовать переключатель:

function toggleFullScreen() { 
    if (!document.fullscreenElement) {   
        document.documentElement.requestFullscreen(); 
    } else {  
        if (document.exitFullscreen) {   
            document.exitFullscreen();  
        } 
    }
}

Анимация элемента при его входе в зону просмотра

See the Pen
Highlight Text as it Enters View with Pure JS
by Eluda (@eludapens)
on CodePen.

Подумайте о тех случаях, когда при попадании элемента в зону видимости вам нужно сделать что-то:

  • анимацию элемента
  • загрузку дальнейшего контента (бесконечная прокрутка)
  • ленивую загрузку изображения
  • регистрацию рекламы.

Наивное решение — вызов getBoundingClientRect при каждом событии прокрутки. Оно рабочее, но жутко неэффективное. Функция запускается в главном потоке, и чем больше слушателей событий мы регистрируем, тем более медленным становится приложение.

К счастью, разработчики браузеров предоставили нам Intersection Observer API. Это эффективное решение, которое делегирует все оптимизации браузеру, благодаря чему разработчик может сосредоточиться на главном.

Для примера мы реализуем очень крутой эффект: части текста будут выделяться по мере попадания в зону просмотра. Такая анимация непременно понравится пользователям. Попробовать ее в действии можно в Codepen выше.

Создание наблюдателя

Прежде чем начать прослушивать события пересечения, нам нужно создать объект observer, который будет управлять всеми фоновыми задачами.

const options = {  
    root: null, // use viewport  
    threshold: 0.75
}

const observer = new IntersectionObserver(callback, options)

Вы, вероятно, заметили threshold. Эта опция велит браузеру запускать события пересечения, когда N% элемента находится в зоне видимости.

Управление событиями пересечения

Давайте определим callback — функцию, которая будет вызываться при наступлении события пересечения.

Мы хотим обрабатывать это событие только когда в зоне видимости находится как минимум N% элемента:

function callback(entry) {
  if (entry.intersectionRatio > 0.75) {
    // ...
  }
}

Пора определить, что делать с элементом, когда он попадает в зону просмотра. В этом случае мы просто назначаем ему имя класса .active, делегируя ответственность за анимацию CSS.

function callback(entry) {
  if (entry.intersectionRatio > 0.75) {
    entry.target.classList.add('active')
  }
}

Мы также можем отменить этот эффект, как только элемент покинет экран:

function callback(entry) {
  if (entry.intersectionRatio > 0.75) {
    entry.target.classList.add('active')
  } else {
    entry.target.classList.remove('active')
  }
}

Более глубокое вступление в IntersectionObserver API можно почитать в прекрасной статье Дениса Мишунова «Now You See Me: How To Defer, Lazy-Load And Act With IntersectionObserver».

Предотвращение выключения экрана

12 редко используемых веб-API для вашего сайта

Для просмотра длинных видео нужно, чтобы экран оставался включенным, даже если никаких взаимодействий с ним не происходит. Такое поведение обычно можно наблюдать в нативных приложениях, но благодаря Screen Wake Lock API оно доступно и в вебе!

Этот API имеет много других юзкейсов:

  • онлайн-игры
  • презентации
  • рисование
  • камера
  • стриминг
  • таймеры
  • список можно продолжать еще долго.

Давайте заглянем во внутреннюю работу API.

Примечание. Firefox и Safari пока не поддерживают этот функционал. Поэтому, чтобы избежать ненужных ошибок, добавляйте проверку доступности: if ('wakelock' in navigator)

Получение wakelock

Видеоплеер, например YouTube, может получить wakelock в своей функции play:

let wakelock = null

async function play() {
    // … 
    wakelock = await navigator.wakeLock.request('screen')
}

Если батарея пользователя разряжена, это не сработает.

Освобождение wakelock

Удерживать wakelock постоянно — плохая практика. Это садит батарею пользователя и может даже снизить производительность. Поэтому всегда освобождайте wakelock, когда это возможно:

async function pause() {
  // ...
  await wakelock.release()
}

Когда пользователь покидает вкладку вашего сайта, wakelock автоматически освобождается.

В этом случае нужно заново получить его, прослушивая событие visibilitychange, о котором мы еще поговорим.

Но в целом это событие триггерится, когда пользователь покидает вкладку сайта или возвращается к ней.

document.addEventListener('visibilitychange', async () => {  
    if (wadocument.addEventListener('visibilitychange', async () => {  
    if (wakelock !== null && document.visibilityState === 'visible') {    
        wakelock = await navigator.wakeLock.request('screen')  
    }
})

Запись экрана

See the Pen
Screen Capture API
by Eluda (@eludapens)
on CodePen.

Количество приложений для записи с экрана постоянно растет. Но как они устроены? Ответ удивительно прост.

Секрет их успеха — Screen Capture API, простой в использовании интерфейс, позволяющий пользователям записывать происходящее на экране разными способами:

  • весь экран
  • конкретное окно
  • конкретную вкладку

Этот API также имеет несколько дополнительных функций, включая:

  • размытие/скрытие перекрывающих окон (чтобы случайно не засветить конфиденциальную информацию)
  • скрытие курсора
  • запись звука.

Браузерная совместимость

Ненавижу приносить плохие новости, но мобильные браузеры пока не поддерживают этот API.

Зато он хорошо поддерживается современными десктопными навигаторами!

Начало записи экрана

Запись экрана при помощи этого API поразительно проста:

const options = {
    video: {
        cursor: 'always' // show the cursor
    },
    audio: false // don't record audio
}
navigator.mediaDevices.getDisplayMedia(options) // returns a promise

Это может показаться невероятным, но это и все!

12 редко используемых веб-API для вашего сайта

Функция в нашем сниппете велит браузеру показать предложение для выбора желаемого объекта (весь экран, окно, вкладка). Вы можете попробовать это в действии при помощи Codepen в начале раздела.

Предпросмотр записи

Было бы хорошо иметь возможность увидеть, что именно видит сайт. К счастью, это тоже на удивление просто сделать:

<video autoplay id="preview"></video>

По части HTML это все, переходим к JavaScript-логике:

previewElem = document.getElementById('preview')
previewElem.srcObject = await navigator.mediaDevices.getDisplayMedia(options)

Готово! Теперь вы можете видеть, что у вас записывается, в режиме реального времени.

Прекращение записи

Один метод позволяет добиться всего! Обратите внимание: важно сначала расположить элемент предпросмотра, как показано в последнем подразделе.

let tracks = previewElem.srcObject.getTracks()

tracks.forEach(() => track.stop())
previewElem.srcObject = null

Сохранение табличных данных в базе данных устройства

See the Pen
Contacts List
by Eluda (@eludapens)
on CodePen.

В вашем браузере спрятана целая NoSQL база данных, а доступ к ней можно получить при помощи IndexedDB API!

Все операции асинхронны, поэтому не замедляют друг друга. База очищается, когда пользователь стирает кэш браузера или данные, сохраненные локально.

Кроме того, этот API поддерживает обычные операции поиска, получения и вставки. Данные можно сохранять любые, включая File, изображения и видео (как Blob) и, конечно, String.

К сожалению, не все браузеры придерживаются единого мнения о том, какие данные стоит поддерживать. Например, Safari на iOS не может сохранять Blob-данные. Но можно конвертировать все другие форматы в ArrayBuffer, который хорошо поддерживается всеми платформами.

Ограничение хранилища — не проблема: большинство браузеров выделяют довольно много пространства, которое ваш сайт может свободно использовать. Кроме того, каждая база данных привязана не только к доменному имени, но и к очень специфичному поддомену. А о браузерной совместимости вообще не стоит беспокоиться, даже в IE11.

Есть много вещей, которые мы можем делать благодаря этим свойствам API, включая:

  • хранение структурированных данных для использования офлайн
  • ускорение загрузки при повторных посещениях
  • кеширование данных, сгенерированных пользователем
  • временное сохранение данных перед загрузкой на сервер.

Давайте посмотрим, как реализовать хранение контактов в IndexedDB!

Использование IndexedDB

Прежде чем мы сможем что-либо сделать, нужно применить библиотеку-обертку IndexedDB, потому что по умолчанию там все сложно и используются события вместо промисов.

import { openDB } from 'idb';

const db = await openDB('contacts', 1, {
    // Creates a new database if it doesn't exist.
    upgrade(db) {
        db.createObjectStore('contacts', {
            // The 'id' property of the object will be the key.
            keyPath: 'id',
            // If it isn't explicitly set, create a value by auto incrementing.
            autoIncrement: true,
        })

        // Create an index on the 'name' property of the objects.
        store.createIndex('name', 'name');
    }
})

Когда все готово, можно начать сохранять структурированные данные.

await db.add('contacts', {
    name: 'John Doe',
    age: 25,
    email: '[email protected]'
})

Получать их тоже легко:

// Get all contacts in name order:
const contacts = await db.getAllFromIndex('contacts', 'name')

Это все, что нам нужно знать об IndexedDB API для нашего простого юзкейса. Но если вам интересно, можете копнуть глубже, почитав документацию.

Сохранение текстовых данных на устройстве даже при выходе пользователя

12 редко используемых веб-API для вашего сайта

Для хранения объемных и сложных данных в браузере мы можем использовать IndexedDB. Но важно также подумать о случаях, когда нужно сохранить простую пару ключ-значение:

  • информация о входе в систему
  • состояние подписки на рассылку
  • принятие cookies
  • пиксели отслеживания

Важно: конфиденциальная информация (пароли, данные кредитных карт, номера социального страхования и т. п.) никогда не должна сохраняться в браузерах из-за подверженности хранилищ XSS-атакам, не говоря уже о других уязвимостях.

Для таких случаев есть специальное решение — Web Storage API. Как и в случае с IndexedDB, хранилище привязывается к определенному поддомену и очищается, когда пользователь стирает кеш браузера или данные.

В этом API вы найдете два типа хранилищ: localStorage и sessionStorage. Каждое имеет свои преимущества:

  • Локальное хранилище сохраняет данные, даже если пользователь покидает сайт. Хранилище сессии очищает все данные, как только закрывается вкладка.
  • Локальное хранилище может сохранять больше данных, а сессионное ограничено 5MB.

Использование локального хранилища

Допустим, нам нужно реализовать форму для подписки на рассылку. Мы не хотим показывать ее уже подписавшимся пользователям, поэтому используем глобальную переменную localStorage, чтобы задействовать условие показа:

function subscribe() {
    // ...
    localStorage.setItem('is-newsletter-subscribed', true)
}

При помощи DevTools вы можете увидеть новый элемент, сохраненный на вашем компьютере.

А теперь давайте напишем функцию, которая будет определять, стоит ли показывать форму подписки:

function isSubscribed() {
    return localStorage.hasOwnProperty('is-newsletter-subscribed') ? localStorage.getItem('is-newsletter-subscribed') : false
}

Как видите, сперва мы проверяем, существует ли элемент newsletter-subscribed. Если да — просто возвращаем его значение при помощи getItem(). В противном случае возвращаем false, потому что пользователь еще не подписался.

Создание волнового эффекта с учетом положения курсора

See the Pen
CSS Location-Aware Ripple Effect
by Eluda (@eludapens)
on CodePen.

С развитием веба спецэффекты тоже развились. Сегодня CSS-свойств уже не хватает для реализации всех наших хотелок.

Нашей последней надеждой было использование GIF и изображений, но с появлением CSS Painting API все изменилось!

Теперь мы можем применять все стилевые эффекты, поставляемые с HTML Canvas, для рисования чего угодно на фоне элементов.

Браузерная совместимость так себе. Firefox и Safari на iOS пока это не поддерживают. Поэтому важно запускать следующий код: if ('paintWorklet' in CSS)

Давайте создадим волновой эффект, не используя псевдоэлементы. (Источник вдохновения — реализация Google).

От редакции Techrocks: о применении CSS Paint API также можно почитать в статье «Эффект фрагментации изображений при помощи CSS Paint API».

JavaScript-логика

Чтобы этот эффект работал, нам нужно использовать события JavaScript для получения координат курсора:

// index.js

button.addEventListener('click', (e) => {
    const {x: offsetX, y: offsetY} = button.getBoundingClientRect()
    const [x, y] = [e.clientX - offsetX, e.clientY - offsetY]

    button.style.setProperty('--x', x)
    button.style.setProperty('--y', y)
    // ...
})

Поскольку волновой эффект — это анимация, привязанная ко времени, нам нужно отслеживать ее продолжительность при помощи переменной tick:

// index.js

button.addEventListener('click', (e) => {
    // ...

    const start = performance.now()
    requestAnimationFrame(function step(now) {
        const tick = Math.floor(now - start)
        button.style.setProperty('--tick', tick)

        // Continue animation
        requestAnimationFrame(step)
    })
})

Этот код для создания эффективной и оптимизированной анимации использует [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). На каждом шаге анимации мы вычисляем tick и присваиваем его CSS-свойству.

Если мы оставим все, как есть, код будет работать вечно. Поэтому давайте добавим условие выхода в конце анимации. Мы остановим анимацию, когда ее продолжительность достигнет одной секунды (т. е. 1000мс):

// index.js

button.addEventListener('click', (e) => {
    // ...

    requestAnimationFrame(function step(now) {
        const tick = Math.floor(now - start)
        button.style.setProperty('--tick', tick)

        // Stop the animation after 1 second
        if (tick > 1000) {
            button.style.setProperty('--tick', 0)
            return
        }

        // Continue animation
        requestAnimationFrame(step)
    })
})

С логикой покончено!

Paint Worklet

Теперь давайте создадим сам волновой эффект при помощи Paint API.

Этот эффект должен содержаться в отдельном файле; назовем его ripple.js.

Начнем с получения CSS-свойств, которые мы только что определили:

// ripple.js

registerPaint('ripple', class {
    static get inputProperties() {
        return ['--x', '--y', '--tick']
    }
})

Далее мы используем Canvas API для рисования круга на фоне кнопки:

// ripple.js

registerPaint('ripple', class {
    //...

    paint(ctx, {width}, props) { 
        // Retrieve props
        const x = parseFloat(props.get('--x').toString())
        const y = parseFloat(props.get('--y').toString())
        let tick = parseFloat(props.get('--tick').toString())

        // Clamp tick in [0, 1000]
        if (tick < 0) tick = 0
        if (tick > 1000) tick = 1000

        // Draw ripple
        const rippleColor = 'rgba(255,255,255,0.54)'
        ctx.fillStyle = rippleColor
        ctx.globalAlpha = 1 - tick/1000
        ctx.arc(
            x, y, // center
            width * tick/1000, // radius
            0, 2 * Math.PI // full circle
        )

        ctx.fill()
    }
})

Регистрация ворклета

Возвращаемся к нашему файлу index.js и добавляем в него следующий код:

// index.js

if ('paintWorklet' in CSS) {
    CSS.paintWorklet.addModule('ripple.js')
}

Этот код сперва будет проверять поддержку CSS Paint API, а затем подключать волновой эффект.

Готово! Осталось только использовать наш эффект. Для этого добавляем следующий код в CSS:

button {
    background-color: #0d1117;
    background-image: paint(ripple);
}

Подробнее почитать о CSS Paint API можно в прекрасной статье «A Practical Overview Of CSS Houdini», автор — Adrian Bece.

Показ нативного меню для шеринга

See the Pen
URL Share
by Eluda (@eludapens)
on CodePen.

В вебе много контента, которым нам хотелось бы поделиться с друзьями:

  • ссылки
  • картинки
  • статьи и т.д.

Обычно разработчики реализуют собственные системы шеринга со ссылками на Twitter, Facebook и другие соцсети.

Но эти компоненты всегда проигрывают своим нативным конкурентам, имеющим целую кучу дополнительных опций:

  • поделиться с контактами
  • опубликовать в других приложениях
  • поделиться через блютуз
  • скопировать в буфер обмена и т. д.

Эти меню для шеринга были эксклюзивной фичей нативных приложений, но благодаря Web Share API мы теперь тоже можем их использовать.

Что касается браузерной поддержки этого функционала, в мобильных браузерах она превосходна, а вот в десктопном Firefox возникают проблемы.

Попробуйте воспользоваться этим меню в Codepen и, если на вашем устройстве эта фича не работает, вы можете увидеть следующую картинку:

12 редко используемых веб-API для вашего сайта

Шеринг URL

Метод для поиска — navigator.share. Он принимает объект, содержащий заголовок, строку текста и URL.

const shareData = {
  title: 'Smashing Magazine',
  text: 'Smashing Magazine — For Web Designers And Developers',
  url: 'https://www.smashingmagazine.com/'
}

await navigator.share(shareData)

Обратите внимание, что эта функция защищена transient activation: для ее обработки необходимо наступление UI-события (например, клик).

Копирование текста в буфер

See the Pen
URL Copy to Clipboard
by Eluda (@eludapens)
on CodePen.

Буфер — одна из самых недооцененных функций сегодняшних компьютеров. Смогли бы мы работать без постоянного Ctrl+C кода со Stackoverflow? Сомневаюсь.

Буфер — это про перемещение цифровой информации из точки А в точку Б. Единственная альтернатива — переписывание контента вручную, а это гарантированный источник ошибок. Современные буферы также позволяют копировать изображения и другие формы медиа.

С появлением Clipboard API разработчики могут существенно улучшить пользовательский опыт за счет предоставления пользователю удобного способа копипаста. Эту фичу можно увидеть повсюду, от кода на сайте MDN до Twitter. Ее нет только на Stackoverflow, и сделано это не без причины.

Браузерная поддержка этого функционала хорошая, за исключением IE, конечно же.

Использование Clipboard API

Копировать текст очень просто:

await navigator.clipboard.writeText('Howdy, partner!')

Да и читать не сложнее:

const text = await navigator.clipboard.readText()

Шеринг выделенного текста

12 редко используемых веб-API для вашего сайта

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

Мы уже рассматривали, как вызывать нативное меню для шеринга, так что здесь давайте сосредоточимся на тексте.

Также мы не будем рассматривать, как добавить набор инструментов над выделенным текстом. Вместо этого мы сосредоточимся на использовании Selection API для получения выделенной части текста.

Что касается браузерной поддержки этой фичи, она превосходна!

Получение выделенного текста

Тут все очень просто:

const text = window.getSelection().toString()

Вот и все! Теперь вернитесь к разделу про Web Share API и создайте всплывающее меню для шеринга в соответствии с ОС, и порадуйте своих пользователей новой фичей!

Изменение тайтла веб-странцы, когда пользователь покидает вкладку

12 редко используемых веб-API для вашего сайта

Сайт может сообщать о том, просматривают его в данный момент или нет, при помощи Page Visibility API.

Хотя я не советую использовать Page Visibility API для привлечения внимания пользователя, этот функционал может иметь много полезных применений:

  • показ новых уведомлений
  • аналитика вовлеченности
  • постановка на паузу видео и аудио
  • остановка карусели изображений.

С браузерной поддержкой проблем нет.

Определение видимости страницы

Мы можем получить информацию о том, видна ли страница пользователю, при помощи следующего кода:

document.visibilityState // 'visible' or 'hidden'

Но настоящие юзкейсы требуют прослушивания событий и соответствующего изменения поведения.

К сожалению, названия событий варьируются от браузера к браузеру, так что нам придется сделать так:

let hidden;
let visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}

Затем мы можем реализовать прослушивание событий видимости страницы:

document.addEventListener(visibilityChange, handleVisibilityChange);

function handleVisibilityChange() {
  if (document[hidden]) {
    // page is hidden
  } else {
    // page is visible
  }
}

Чтобы показать, как это работает, просто изменим тайтл документа:

function handleVisibilityChange() {
  if (document[hidden]) {
    document.title = 'Please stay!!!'
  } else {
    document.title = 'Shopping website'
  }
}

Обратите внимание: я не советую так делать. Это раздражает пользователей и не соответствует практике этичного веб-дизайна.

Заключение

Сегодня веб-API заполняют пробел между нативными и веб-приложениями.

Веб начинает становиться реальной угрозой для монополий, созданных App Store и Google Play Store, и не похоже, чтобы этот процесс собирался затормозить.

Конечно, в этой статье мы рассмотрели не все интересные API. Если еще такие вещи, как сканирование штрихкодов и распознавание речи, но о них поговорим как-нибудь потом.

Перевод статьи «12 Rarely Used JavaScript Web APIs that Will Boost Your Website to THE MOON».

Запись 12 редко используемых веб-API для вашего сайта впервые появилась Techrocks.