检查浏览器选项卡是否在 ReactJS 中处于焦点

IT技术 reactjs
2021-05-01 05:29:15

我在 ReactJS 中有一个网站。每当我的选项卡成为焦点或隐藏时,我都想获得回调。我为此遇到了页面可见性 API,但我无法弄清楚如何在 ReactJS 中使用它。

我在哪个生命周期方法中为此注册回调?

4个回答

刚刚使用 React 16.8 的钩子构建了这个

import React, { useEffect } from 'react';

// User has switched back to the tab
const onFocus = () => {
  console.log('Tab is in focus');
};

// User has switched away from the tab (AKA tab is hidden)
const onBlur = () => {
  console.log('Tab is blurred');
};

const WindowFocusHandler = () => {
  useEffect(() => {
    window.addEventListener('focus', onFocus);
    window.addEventListener('blur', onBlur);
    // Specify how to clean up after this effect:
    return () => {
      window.removeEventListener('focus', onFocus);
      window.removeEventListener('blur', onBlur);
    };
  });

  return <></>;
};

export default WindowFocusHandler;

这应该有效:

componentDidMount() {
    window.addEventListener("focus", this.onFocus)
}

componentWillUnmount() {
    window.removeEventListener("focus", this.onFocus)
}

onFocus = () => {
    //
}

编辑:“模糊”也是如此,它应该在选项卡隐藏时起作用。

检查@Assaf 的答案是否与钩子一起使用。

没有可靠的方法来检查它,因此您需要将几种方法组合在一起。这是react-hooks的上下文

import React, { useState, useEffect } from 'react'

export const WindowContext = React.createContext(null)

export const WindowContextProvider = props => {
  const [windowIsActive, setWindowIsActive] = useState(true)


  function handleActivity(forcedFlag) {
    if (typeof forcedFlag === 'boolean') {
      return forcedFlag ? setWindowIsActive(true) : setWindowIsActive(false)
    }

    return document.hidden ? setWindowIsActive(false) : setWindowIsActive(true)
  }

  useEffect(() => {
    const handleActivityFalse = () => handleActivity(false)
    const handleActivityTrue = () => handleActivity(true)

    document.addEventListener('visibilitychange', handleActivity)
    document.addEventListener('blur', handleActivityFalse)
    window.addEventListener('blur', handleActivityFalse)
    window.addEventListener('focus', handleActivityTrue )
    document.addEventListener('focus', handleActivityTrue)

    return () => {
      window.removeEventListener('blur', handleActivity)
      document.removeEventListener('blur', handleActivityFalse)
      window.removeEventListener('focus', handleActivityFalse)
      document.removeEventListener('focus', handleActivityTrue )
      document.removeEventListener('visibilitychange', handleActivityTrue )
    }
  }, [])

  return <WindowContext.Provider value={{ windowIsActive }}>{props.children}</WindowContext.Provider>
}

我找到了这个图书馆它可能会有所帮助。

这是我将如何使用它来解决您的问题

import React from 'react';
import PageVisibility from 'react-page-visibility';

class YourComponent extends React.Component {
    state = {
      isWindowInFocus: true,
    }
    componentDidMount() {
      const { isWindowInFocus } = this.props;
      if (!isWindowInFocus) {
        // do something
      }
    }

    listentoWindow = isVisible => {
      this.setState({
        isWindowInFocus: isVisible,
      });
    }
    render() {
      return (
        <PageVisibility onChange={this.listentoWindow}>
          <div>
           Your component JSX
          </div>
        </PageVisibility>
      );
    }
}