【问题标题】:React.js - trigger "useEffect" ONLY if page is active (page-load or reload)React.js - 仅在页面处于活动状态(页面加载或重新加载)时触发“useEffect”
【发布时间】:2021-08-04 22:50:54
【问题描述】:

TL;DR

"Vanilla-JS 应用程序在用户在页面上处于活动状态时执行代码,而 React 组件在组件加载到 DOM 时立即执行代码(即使用户在页面上不活跃


我正在开发一个 React 网站并使用“CSS 过渡”创建一个 SVG 动画,该动画通过向元素添加一个类来触发。下面是 React 代码

useEffect(() => {    
function startAnimation() {
    var wrapper = document.querySelector('svg#logo');
    wrapper.classList.add('active');
}
}, []);

我最初在 Vanilla-JS 项目中创建了它(使用 jQuery 的 $(document).ready() 函数),然后将其转换为 React 组件。但我注意到 Vanilla-JS 应用程序中的转换仅在页面处于活动状态时才会启动,而 React 组件会在组件加载到 DOM 时立即启动转换(即使用户在页面上未处于活动状态)。

我知道这是因为我使用了 useEffect 钩子,但是我们如何才能使用 React 获得与 $(document).ready() 相同的行为呢?

下面是 Vanialla-JS 代码

$(document).ready(function () {
function logoDraw() {
  var wrapper = document.querySelector('svg#logo')
  wrapper.classList.add('active')
}

  setTimeout(logoDraw, 10)
});

更新:

  • 基于另一个问题的the answer,我使用“焦点”事件侦听器仅在页面处于焦点时才启动动画。但是在这样做之后,如果我重新加载页面并保持在同一页面中,则不会启动转换。只有在我切换标签时才会启动它。
  • 我发现了一个 related question,它指出“在第一次加载页面时,它已经有了焦点,因此没有引发任何事件”

【问题讨论】:

    标签: html css reactjs svg


    【解决方案1】:

    经过几个小时的在线搜索,我终于在一篇名为“Harnessing the Page Visibility API with React”的博文中找到了完美的答案。

    它做两件事之一:

    1. 检测页面是否已经处于活动状态并立即执行代码(即使重新加载也可以工作
    2. 等待选项卡激活并执行代码。

    该博客详细介绍了它的工作原理,Seth Corker(该博客的所有者)还主持了 demo


    如果页面处于活动状态,我们可以使用“Page Visibility API”并使用“useEffect”挂钩根据需要对任何 DOM 元素进行更改。

    请在下面找到来自上述博客的工作代码的示例副本。

    function getBrowserVisibilityProp() {
        if (typeof document.hidden !== "undefined") {
            // Opera 12.10 and Firefox 18 and later support
            return "visibilitychange"
        } else if (typeof document.msHidden !== "undefined") {
            return "msvisibilitychange"
        } else if (typeof document.webkitHidden !== "undefined") {
            return "webkitvisibilitychange"
        }
    }
    
    function getBrowserDocumentHiddenProp() {
        if (typeof document.hidden !== "undefined") {
            return "hidden"
        } else if (typeof document.msHidden !== "undefined") {
            return "msHidden"
        } else if (typeof document.webkitHidden !== "undefined") {
            return "webkitHidden"
        }
    }
    
    function getIsDocumentHidden() {
        return !document[getBrowserDocumentHiddenProp()]
    }
    
    function usePageVisibility() {
        const [isVisible, setIsVisible] = React.useState(getIsDocumentHidden())
        const onVisibilityChange = () => setIsVisible(getIsDocumentHidden())
    
        React.useEffect(() => {
            const visibilityChange = getBrowserVisibilityProp()
    
            document.addEventListener(visibilityChange, onVisibilityChange, false)
    
            return () => {
                document.removeEventListener(visibilityChange, onVisibilityChange)
            }
        })
    
        return isVisible
    }
    
    // Above code uses Page_Visibility_API
    // Below is a simple React code
    
    const App = (props) => {
        const [counter, setCounter] = React.useState(0);
        const isVisible = usePageVisibility();
        const delay = 1000;
    
    
        React.useEffect(() => {
            const timeout = setTimeout(() => {
                if (isVisible) {
                    setCounter(counter + 1);
                }
            }, delay);
    
            return () => {
                clearTimeout(timeout);
            };
        });
    
    
    
        return (
            <div>
                <p>Below number gets updated every {delay / 1000} second only if the page is active</p>
                <span id="output">{counter}</span>
            </div>
        );
    };
    
    ReactDOM.render(<App />, document.getElementById("root"));
    #output{
      font-size: xx-large
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多