TGViewer
mefody.dev mefody.dev @mefody_dev · 5.39K subscribers
Post #33 1.45K
User Activation API

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

Допустим, у вас есть такой код:

let audioCtx = new AudioContext();
await navigator.share({text: 'test'});
window.open('mefody.dev');


Если этот код просто вызвать сразу при загрузке страницы, то он упадёт с ошибками NotAllowedError. И это ожидаемое поведение — таким образом браузер защищает пользователя от назойливого поведения веб-страниц вроде попапов, внезапного звука, неожиданной оплаты через Apple Pay и так далее.

Чтобы он заработал, нужно обернуть код в addEventListener одного из следующих событий: keydown, mousedown, pointerdown (если pointerType равен mouse), pointerup (если pointerType не равен mouse), touchend. Таким образом браузер будет уверен, что всякое назойливое произошло уже после того, как пользователь начал взаимодействовать со страницей. То есть как будто он сам нажал кнопку «Воспроизвести» и ожидает подобное поведение страницы.

Но если вы напишете такой код:

button.addEventListener('click', async () => {
let audioCtx = new AudioContext();
await navigator.share({text: 'test'});
window.open('mefody.dev');
});

он, на удивление, всё равно не будет работать. Аудиоконтекст создастся, окно шаринга покажется, а вот ссылка не откроется. Дело в том, что window.open мешают две особенности таких обработчиков.

Для начала, пользовательская активация бывает временная (transient) и постоянная (sticky). Когда срабатывает обработчик пользовательской активации, в браузере запускается таймер, во время которого можно выполнять методы API, требующие этой самой активации. Это довольно короткий промежуток, буквально пара секунд. В нашем случае share съедает время этого таймера, на window.open нужно триггерить активацию снова. Это называется временной активацией.

Некоторые API не требуют срабатывания до истечения таймера. Им достаточно знания, что активация была когда-то на странице. Такая активация называется постоянной. Для работы с Web Audio, например, достаточно всего одного клика на странице. Объясняется это тем, что если бы пользователю приходилось кликать по странице на каждый чих внутри узлов работы с аудио, это был бы самый ужасный интерфейс.

Но допустим, что пользователь успеет пошарить что-то буквально за доли секунды, до истечения таймера. Сработает ли window.open? Всё равно нет. Тут вступает в дело другой механизм — потребление активации. Некоторые API, как только получает возможность выполниться, «потребляют» активацию, то есть сбрасывают таймер. Среди таких методов: requestPermission, show для Payment Request и тот самый share. Этот список может пополняться и зависеть от браузера.

Так как же проверять, что активация сработала и я могу вызывать свои методы? Для этого есть navigator.userActivation.isActive для проверки временной активации и navigator.userActivation.hasBeenActive для проверки постоянной активации.

https://webkit.org/blog/13862/the-user-activation-api/
WebKit The User Activation API As a web developer, you’ve probably noticed that certain APIs only work if an end-user clicks or taps on an HTML element.
  • 👍 20
  • 🔥 7
  • 🤯 5
More from @mefody_dev
  1. Sep 28, 2026View Transitions Toolkit Брамус делится своей коллекцией утилит, чтобы можно было более уд…
  2. Sep 25, 2026Эффект одометра Люблю такие демки, когда на чистом CSS делают что-то необычное, для чего я…
  3. Sep 23, 2026Цена ошибок гидрации В React есть много ухищрений, чтобы серверный кусок страницы обновилс…
  4. Sep 16, 2026Какие анимации более производительные: CSS или JS? Лучше пару раз увидеть, чем много откуд…
  5. Sep 14, 2026Единица измерения lh Если коротко, то 1lh = 1 line height. И это не размер шрифта, который…
  6. Sep 11, 2026<mermaid-element> Ещё одна полезная библиотека. Брамус собрал кастомный элемент, которому…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →