DOM 渲染后在 React 中执行 Vanilla JS 脚本

Posted

技术标签:

【中文标题】DOM 渲染后在 React 中执行 Vanilla JS 脚本【英文标题】:Execute Vanilla JS Scripts in React after DOM Render 【发布时间】:2021-12-15 19:01:52 【问题描述】:

我花了 5 个小时努力摆脱这个问题,我已将一些 <script> 标签放入位于 public 文件夹中的 index.html 文件中。 我希望它们在浏览器完全呈现 HTML 后执行,我知道这是非常基本的问题,但问题是,我正在将 HTML 模板转换为 React,并且它大量使用动画,我负担不起从头开始再次写下反应。这是我的代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Galaxy App</title>

    <!--CSS-->
    <link href="asset/css/icofont.min.css" rel="stylesheet" />
    <link href="asset/css/linearicons.min.css" rel="stylesheet" />
    <link href="asset/css/magnific-popup.min.css" rel="stylesheet" />
    <link href="asset/css/animsition.min.css" rel="stylesheet" />
    <link href="asset/css/bootstrap.min.css" rel="stylesheet" />
    <link href="asset/css/swiper.min.css" rel="stylesheet" />
    <link href="asset/css/styles.css" rel="stylesheet" />
    <link href="asset/css/main.css" rel="stylesheet" />
    <link href="asset/css/homepage.css" rel="stylesheet" />


    <!--Theme CSS-->
    <link href="asset/css/theme.css" rel="stylesheet" />
    <link href="asset/css/responsive.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.js"></script>

    <script src="asset/js/polyfill.min.js"></script>
    <script src="asset/js/jquery.min.js"></script>
    <script src="asset/js/jquery.viewport.min.js"></script>
    <script src="asset/js/jQuerySimpleCounter.min.js"></script>
    <script src="asset/js/jquery.magnific-popup.min.js"></script>
    <script src="asset/js/animsition.min.js"></script>
    <script src="asset/js/isotope.pkgd.min.js"></script>
    <script src="asset/js/bootstrap.bundle.min.js"></script>
    <script src="asset/js/rellax.min.js"></script>
    <script src="asset/js/swiper.min.js"></script>
    <script src="asset/js/smoothscroll.js"></script>
    <script src="asset/js/svg4everybody.legacy.min.js"></script>
    <script src="asset/js/TweenMax.min.js"></script>
    <script src="asset/js/TimelineLite.min.js"></script>
    <script src="asset/js/typed.min.js"></script>
    <script src="asset/js/vivus.min.js"></script>
    <script src="asset/js/main.js"></script>
    <!-- Theme JS -->
    <script src="asset/js/theme.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.js"></script>
    <script src="asset/js/cutsom.js"></script>
  </body>
</html>

我通过在最后一个脚本中记录 document.getElementById() 手动检查,它返回 undefined/null 因为那时 HTML 没有完全呈现,即使我已将脚本放在文件末尾。 如果我在我的脚本中添加setTimeout,它就可以工作,并且它可以完美地捕获元素。

那么我应该怎么做才能只在我的 HTML 完全呈现时才加载所有脚本。

【问题讨论】:

不知何故你必须知道 React 何时完成渲染。您可以将回调函数传递给ReactDOM.render 并从那里触发任何其他处理:reactjs.org/docs/react-dom.html#render。这可能需要稍微重构现有代码以使其可按需调用。但是请注意,在 React 的控制下从外部更改 DOM 元素通常是不可行的。 我想你应该使用类似的答案来回答这个问题。 ***.com/questions/34424845/… 【参考方案1】:

实现此目的的一种方法是从 React 发出 Event。

将此添加到您的主要反应组件中:

useEffect(() => 
    const event = new Event('rendered')
    document.dispatchEvent(event)
, [])

监听页面上的事件:

<script>
    document.addEventListener('rendered', function() 
      // start animation
    , false)
</script>

【讨论】:

以上是关于DOM 渲染后在 React 中执行 Vanilla JS 脚本的主要内容,如果未能解决你的问题,请参考以下文章

编辑数组后在 React 中重新渲染子组件数组

react父子组件生命周期执行顺序

React的数据渲染循环key的作用

React - 在 DOM 渲染时加载屏幕?

react怎么通过函数控制渲染dom

React,如何从同一个组件访问我的渲染函数中的 DOM 元素