При створенні веб-додатки ви можете зіткнутися з ситуаціями, коли потрібно відстежити поточний стан видимості. Буває, що потрібно відтворити або призупинити ефект анімації або відео, зменшити інтенсивність або відстежити поведінку користувача для аналітики. На перший погляд ця функція здається досить простий для реалізації, але це не зовсім так. Відстеження активності користувача - досить складний процес.
Є Page Visibility API, який відмінно працює в більшості випадків, але не перетворює всі можливі випадки неактивності вкладки браузера. Page Visibility API відправляє подія visibilitychange, щоб listeners знали, що стан видимості сторінки змінився. Він не запускає подія в деяких випадках, якщо вікно або відповідна вкладка браузера приховані з уваги. Щоб обробляти деякі з цих випадків, нам потрібно використовувати комбінацію подій focus і blur як в document, так і на window.
Отже, з цієї статті ви дізнаєтеся, як створити простий React-компонент, який відстежує Page Visibility State.
кроки
Для створення React-додатки тут буде використаний Codesandbox (ви також можете використовувати create-react-app). Ми створимо невеликий додаток, в якому HTML5-елемент video буде відтворюватися тільки в тому випадку, якщо вкладка браузера знаходиться у фокусі або активна, інакше він буде припинений автоматично. Video використовується, щоб полегшити тестування функцій програми.
1. Почніть з створення найпростішої частини, тобто компонента video. Це буде простий компонент з параметрами Boolean active і String src, що містить URL-адресу для video. Якщо active props істинно, video буде відтворюватися. В іншому випадку воно буде зупинено.
2. Створіть простий React-клас і елемент video з його вихідним кодом, які приймають URL-адресу, переданий за допомогою src. Тут використовується новий ref API для приєднання посилання до DOM-node video. Налаштуємо video на Автовідтворення, припускаючи, що коли ми запустимо додаток, сторінка буде активна.
Safari не дозволяє автоматично відтворювати елементи мультимедіа без взаємодії з користувачем. Метод componentDidUpdate дуже зручний при обробці ефектів при зміні властивості компонента. Тому тут буде використаний цей метод для відтворення та призупинення відео на основі поточного значення this.props.active.3. Створіть функцію утиліти. Відмінності в префіксах браузера не завжди зручні у використанні певних API-інтерфейсів, і Page Visibility API один з них. Ми створимо просту функцію утиліти, яка буде обробляти ці відмінності і повертати єдиний API на основі браузера користувача. Створіть і експортуйте цю функцію з pageVisibilityUtils.js в src directory.
У цій функції будемо використовувати оператор if-else, щоб повернути API-інтерфейс, специфічний для браузера. Видно, що ми додаємо префікс ms для Internet Explorer і префікс webkit для Webkit-браузерів. Ми будемо зберігати потрібний API в hidden і visibilityChange змінних і повертати їх з функції у вигляді простого об`єкта. Нарешті, експортуємо функцію.4. Перейдіть на основний компонент. Ми інкапсуліруем всю логіку відстеження видимості сторінки в використовуваному клас-компоненті React, використовуючи шаблон Render Props. Створіть клас-компонент VisibilityManager. Цей компонент буде обробляти додавання і видалення всіх подій на основі DOM listeners.
5. Почніть з імпорту раніше створеної допоміжної функції і її виклику для отримання правильних API-інтерфейсів браузера. Потім створіть React-компонент і Ініціалізуйте його стан з одним єдиним полем isVisible встановленим в true. Це Boolean поле буде відповідати за стан видимості сторінки.
6. У componentDidMount додайте event listener до document для visibilitychange за допомогою методу this.handleVisibilityChange в якості обробника. Також додайте event listener для подій focus і blur в document, а також елемента window. На цей раз ми встановимо this.forceVisibilityTrue і this.forceVisibilityFalse як обробники для подій focus і blur.
7. Потім створіть метод handleVisibilityChange, який приймає аргумент forceFlag. Аргумент forceFlag буде використовуватися для визначення того, чи викликаний метод через події visibilitychange або подій focus і blur. Це відбувається тому, що методи forceVisibilityTrue і forceVisibilityFalse нічого не роблять, крім виклику методу handleVisibilityChange з істинним і хибним значенням для forceFlag.
8. Усередині методу handleVisibilityChange спочатку перевірте, чи є значення аргументу forceFlag логічним (якщо він викликається з обробника події visibilitychange, то переданий аргумент буде об`єктом SyntheticEvent).
Якщо це Boolean, перевірте, істинно воно або помилково. Коли значення істинно, викликаємо метод setVisibility з true або викликаємо метод з false. Метод setVisibility використовує this.setState метод для оновлення значення isVisible в стані компонента.Якщо forceFlag НЕ Boolean, перевірте значення прихованого атрибута в document і відповідним чином викликаємо метод setVisibility. Це завершує логіку відстеження стану видимості сторінки.9. Зробіть компонент багаторазовим. Для цього використовуйте патерн Render Props. Тобто замість рендеринга компонента з методу render ми викликаємо this.props.children як функцію з this.state.isVisible.
10. Встановіть React-додаток в DOM в файлі index.js. Імпорт два компонента React VisibilityManager і Video і створіть компонент App, з`єднавши їх. Ми передаємо функцію як дочірній елемент компонента VisibilityManager, який приймає на вхід isVisible і передає його компоненту Video на виході. Також передаємо URL-адресу відео як src для компонента Video. Ось як застосовується компонент VisiblityManager на основі Render Props. В кінці використовуємо метод ReactDOM.render для рендеринга додатки на DOM-node з ідентифікатором «root».