Cod*_*tle 5 javascript reactjs
这有点类似于这个问题:
但就我而言,我正在加载这样的脚本:
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','ID');</script>
<!-- End Google Tag Manager -->
Run Code Online (Sandbox Code Playgroud)
现在我知道有一个用于 google 标签管理器的 npm 包,但我很好奇我是否想以自定义方式执行此操作,我该怎么做?
在上面的问题中,我看到了很多:
const script = document.createElement("script");
script.src = "https://use.typekit.net/foobar.js";
script.async = true;
document.body.appendChild(script);
Run Code Online (Sandbox Code Playgroud)
这很好,但如果我在加载的脚本中有一个函数,我将如何正确执行它?
dec*_*ele 12
要添加这样的随机脚本,您可以:
1. 将脚本添加到 HTML
只需将脚本标签粘贴到您的index.html 文件中,最好是在正文标签的末尾。如果使用 create-react-app,index.html 文件位于 public 目录中:
<body>
<div id="root"></div>
<script>/* your script here */</script>
</body>
Run Code Online (Sandbox Code Playgroud)
2. 从文件导入
或者,您可以将脚本粘贴到 .js 文件中,然后从代码中的任何位置导入它。导入通用脚本的好地方是您的 index.js 入口点文件。这种方法的好处是可以将脚本包含在 js 包的其余部分中,从而实现缩小和树摇动。
// index.js
import "../path/to/your/script-file";
Run Code Online (Sandbox Code Playgroud)
3. 代码分割 最后,如果您想在某个时间点动态加载一段 js 代码,同时确保它不是您的起始包的一部分,您可以使用动态导入来进行代码分割。https://create-react-app.dev/docs/code-splitting
function App() {
function handleLoadScript() {
import('./your-script')
.then(({ functionFromModule }) => {
// Use functionFromModule
})
.catch(err => {
// Handle failure
});
};
return <button onClick={handleLoadScript}>Load</button>;
}
Run Code Online (Sandbox Code Playgroud)
通常,我们可以使用 prop. 来更新 React 中的 HTML 元素dangerouslySetInnerHTML。但对于要执行的脚本的情况,这是行不通的,正如在另一个SO问题中讨论的那样。
实现此目的的一个选项是使用文档 Range API createContextualFragment将元素附加到新文档上下文中
下面的工作示例。请注意,我对您的脚本进行了一些调整,以展示一些自定义它的方法。
const { useState, useRef, useEffect, memo } = React;
const MyCustomScriptComponent = () => {
const [includeScript, setIncludeScript] = useState(false)
// just some examples of customizing the literal script definition
const labelName = 'dataLayer'
const gtmId = 'ID' // your GTM id
// declare the custom <script> literal string
const scriptToInject = `
<script>
(function(w,d,s,l,i){
const gtmStart = new Date().getTime();
w[l]=w[l]||[];w[l].push({'gtm.start':
gtmStart,event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
console.log("loaded at gtmStart:", gtmStart);
})(window,document,'script','${labelName}','${gtmId}');
console.log("fetching GTM using id '${gtmId}'");
</script>`
const InjectScript = memo(({ script }) => {
const divRef = useRef(null);
useEffect(() => {
if (divRef.current === null) {
return;
}
// create a contextual fragment that will execute the script
// beware of security concerns!!
const doc = document
.createRange()
.createContextualFragment(script)
// clear the div HTML, and append the doc fragment with the script
divRef.current.innerHTML = ''
divRef.current.appendChild(doc)
})
return <div ref={divRef} />
})
const toggleIncludeScript = () => setIncludeScript((include) => !include)
return (
<div>
{includeScript && <InjectScript script={scriptToInject} />}
<p>Custom script {includeScript ? 'loaded!' : 'not loaded.'}</p>
<button onClick={toggleIncludeScript}>Click to load</button>
</div>
)
}
ReactDOM.render(<MyCustomScriptComponent />, document.getElementById('app'))
Run Code Online (Sandbox Code Playgroud)
在codepen上尝试一下。
如需更多参考,您可以在这篇中等帖子中找到更多注入脚本的替代方法。
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |