I am having following script file
<script language="javascript">
document.write('<script language="javascript" src="http://tickettransaction.com/?bid='+bid+'&sitenumber='+site+'&tid=event_dropdown" ></' + 'script>');
</script>
I follow this Adding script tag to React/JSX but it does not work for me...
How do I load the script in my react component?
After a lots of R&D finally I found my solution.
I have used npm postscribe to load script in react component
postscribe('#mydiv', '<script language="javascript" src="http://tickettransaction.com/?bid='+bid+'&sitenumber='+site+'&tid=event_dropdown"></script>')
A 2021 TypeScript example using functional components that works with NextJS
(ensures code only runs client-side)
declare global {
interface Window {
hbspt: any
}
}
export default function Contact() {
useEffect(() => {
if (window && document) {
const script = document.createElement('script')
const body = document.getElementsByTagName('body')[0]
script.src = '//js.hsforms.net/forms/v2.js'
body.appendChild(script)
script.addEventListener('load', () => {
window.hbspt.forms.create({
// this example embeds a Hubspot form into a React app but you can tweak it for your use case
// any code inside this 'load' listener will run after the script is appended to the page and loaded in the client
})
})
}
}, [])
return <div id="hbspt-form" className="p-5"></div>
}
the following method is worked for me. try, hope it will work for you.
basically, you can create a script tag and append it to the body tag. like this--
var tag = document.createElement('script');
tag.async = true;
tag.src = 'THE PATH TO THE JS FILE OR A CDN LINK';
var body = document.getElementsByTagName('body')[0];
body.appendChild(tag);
you can use this on a life cycle hook of react like this.
componentDidMount() {
var loadScript = function (src) {
var tag = document.createElement('script');
tag.async = false;
tag.src = src;
var body = document.getElementsByTagName('body')[0];
body.appendChild(tag);
}
loadScript('PATH TO THE JS FILE OR CDN URL');
}
I recommend using React Helmet. I've used it on a couple of Create-React-Apps, and it allows you to write actual script tags combined with vanilla JS.
It makes the process a lot smoother. So for you it'd be something like this once you've imported React Helmet.
<script language="javascript" src='http://tickettransaction.com/?bid='+ bid + '&sitenumber='+ site +'&tid=event_dropdown' ></ script>
This came to my rescue. This is the easiest way to load Script Tags
https://www.npmjs.com/package/react-script-tag
import ScriptTag from 'react-script-tag';
const Demo = props => (
<ScriptTag src="/path/to/resource.js" />
);
There are other ways to do this too :
https://medium.com/better-programming/4-ways-of-adding-external-js-files-in-reactjs-823f85de3668
Update 2022
Use https://usehooks-ts.com/react-hook/use-script. This also returns status and allows props like removeOnUnmount.
Most of packages to do the job are outdated at the date. I found a solution that maybe can be useful for someone and it´s using a hook with the advantage you can control the state and take action based on it.
import { useEffect, useState } from 'react';
export const useExternalScript = (url) => {
let [state, setState] = useState(url ? "loading" : "idle");
useEffect(() => {
if (!url) {
setState("idle");
return;
}
let script = document.querySelector(`script[src="${url}"]`);
const handleScript = (e) => {
setState(e.type === "load" ? "ready" : "error");
};
if (!script) {
script = document.createElement("script");
script.type = "application/javascript";
script.src = url;
script.async = true;
document.body.appendChild(script);
script.addEventListener("load", handleScript);
script.addEventListener("error", handleScript);
}
script.addEventListener("load", handleScript);
script.addEventListener("error", handleScript);
return () => {
script.removeEventListener("load", handleScript);
script.removeEventListener("error", handleScript);
};
}, [url]);
return state;
};
Use it is simple as do:
const externalScript = 'https://player.live-video.net/1.6.1/amazon-ivs-player.min.js';
const scriptStatus = useExternalScript(externalScript);
useEffect(() => {
if (scriptStatus === 'ready') {
// Do something with it
}
}, [scriptStatus]);
Update 2022 for Class based as well as Functional components.
You can create a function as below and then use it inside componentDidMount:
function loadScript(url, callback){
let script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
// For class based components
componentDidMount() {
loadScript("scriptUrl", callback());
}
// For functional components
useEffect(() => {
loadScript("scriptUrl", callback());
}, [])
Source: add third-party js library to Create React App
Related
I would like to add to my react component a
<script>http://xxx.xxx/XX.js</script>
I know I can simply add it using JSX , what I don't know is how to use it,
for instance this script has a function called A.Sort() , how can I call it and use it from a component?
You can load the script asynchronously and access it on load.
componentDidMount() {
const script = document.createElement("script");
script.src = "/static/libs/your_script.js";
script.async = true;
script.onload = () => this.scriptLoaded();
document.body.appendChild(script);
}
It should get attached to the window.
scriptLoaded() {
window.A.sort();
}
or
scriptLoaded() {
A.sort();
}
You can include the tag in the /public/index.html, and then use the script as you use it in normal JS code, following example for if you want to use jQuery:
in your public/index.html include the following:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
And then anywhere you can use the jQuery functionality as usual:
window.$("#btn1").click(function(){
alert("Text: " + $("#test").text());
});
You can use React Helmet npm
step 1 : npm i react-helmet
step 2 :
<Helmet>
<script src="/path/to/resource.js" type="text/javascript" />
</Helmet>
Sometimes we need to work with external js libraries in such cases we need to insert script tags into components, but in react we use jsx, so we can’t add script tags directly just like how we add in HTML.
In this example, we will see how to load an external script file into a head, body elements, or component.
componentDidMount() {
const script = document.createElement("script");
script.async = true;
script.src = "https://some-scripturl.js";
script.onload = () => this.scriptLoaded();
//For head
document.head.appendChild(script);
// For body
document.body.appendChild(script);
// For component
this.div.appendChild(script);
}
You can either modify your index.html file (if you are using one) by adding the required script.
Alternatively, if you can't edit it or you are not using it, there's a bunch of add-ons that solve this, for example react-load-script
After adding this script into your index.html
<script>http://xxx.xxx/XX.js</script>
you might check the available functions if you console.log(window) in App.js (or, wherever you want). Once you check the exact function, then you can use it like
window.A.sort();
I think this could be the simplest way. Just remember that you have to write 'window.' on the left side of your function.
If you want to import script in multiple components, then you can create your own custom hook that allows you to insert script in desired component:
import { useEffect } from 'react'
const importScript = src => {
useEffect(() => {
const script = document.createElement('script')
script.src = src
script.async = true
document.body.appendChild(script)
return () => {
document.body.removeChild(script)
}
}, [src])
}
export default importScript
Using it on your desired component:
import importScript from 'import-path'
const DesiredComponent = props => {
importScript("/path/to/resource")
// ... rest of the code
}
A hooks version.
import * as React from "react";
function loadError(onError) {
console.error(`Failed ${onError.target.src} didn't load correctly`);
}
function External() {
React.useEffect(() => {
const LoadExternalScript = () => {
const externalScript = document.createElement("script");
externalScript.onerror = loadError;
externalScript.id = "external";
externalScript.async = true;
externalScript.type = "text/javascript";
externalScript.setAttribute("crossorigin", "anonymous");
document.body.appendChild(externalScript);
externalScript.src = `https://externalurl.example.com/external.js?key=9393ABCDEFGH`;
};
LoadExternalScript();
}, []);
return <></>;
}
export default External;
I want to dynamically include a script tag in a webpage however I have no control of it's src so src="source.js" may look like this.
document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')
Now ordinarily putting
<script type="text/javascript" src="source.js"></script>
In the head works fine but is there any other way I can add source.js dynamically using something like innerHTML?
jsfiddle of what i've tried
var my_awesome_script = document.createElement('script');
my_awesome_script.setAttribute('src','http://example.com/site.js');
document.head.appendChild(my_awesome_script);
You can use the document.createElement() function like this:
function addScript( src ) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
document.body.appendChild( s );
}
There is the onload function, that could be called when the script has loaded successfully:
function addScript( src, callback ) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
s.onload=callback;
document.body.appendChild( s );
}
It's almost a decade later and nobody bothers to write the Promise version, so here is mine (based on this awnser):
function addScript(src) {
return new Promise((resolve, reject) => {
const s = document.createElement('script');
s.setAttribute('src', src);
s.addEventListener('load', resolve);
s.addEventListener('error', reject);
document.body.appendChild(s);
});
}
Usage
try {
await addScript('https://api.stackexchange.com/js/2.0/all.js');
// do something after it was loaded
} catch (e) {
console.log(e);
}
a nice little script I wrote to load multiple scripts:
function scriptLoader(scripts, callback) {
var count = scripts.length;
function urlCallback(url) {
return function () {
console.log(url + ' was loaded (' + --count + ' more scripts remaining).');
if (count < 1) {
callback();
}
};
}
function loadScript(url) {
var s = document.createElement('script');
s.setAttribute('src', url);
s.onload = urlCallback(url);
document.head.appendChild(s);
}
for (var script of scripts) {
loadScript(script);
}
};
usage:
scriptLoader(['a.js','b.js'], function() {
// use code from a.js or b.js
});
When scripts are loaded asynchronously they cannot call document.write. The calls will simply be ignored and a warning will be written to the console.
You can use the following code to load the script dynamically:
var scriptElm = document.createElement('script');
scriptElm.src = 'source.js';
document.body.appendChild(scriptElm);
This approach works well only when your source belongs to a separate file.
But if you have source code as inline functions which you want to load dynamically and want to add other attributes to the script tag, e.g. class, type, etc., then the following snippet would help you:
var scriptElm = document.createElement('script');
scriptElm.setAttribute('class', 'class-name');
var inlineCode = document.createTextNode('alert("hello world")');
scriptElm.appendChild(inlineCode);
document.body.appendChild(scriptElm);
You can try following code snippet.
function addScript(attribute, text, callback) {
var s = document.createElement('script');
for (var attr in attribute) {
s.setAttribute(attr, attribute[attr] ? attribute[attr] : null)
}
s.innerHTML = text;
s.onload = callback;
document.body.appendChild(s);
}
addScript({
src: 'https://www.google.com',
type: 'text/javascript',
async: null
}, '<div>innerHTML</div>', function(){});
A one-liner (no essential difference to the answers above though):
document.body.appendChild(document.createElement('script')).src = 'source.js';
This Is Work For Me.
You Can Check It.
var script_tag = document.createElement('script');
script_tag.setAttribute('src','https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js');
document.head.appendChild(script_tag);
window.onload = function() {
if (window.jQuery) {
// jQuery is loaded
alert("ADD SCRIPT TAG ON HEAD!");
} else {
// jQuery is not loaded
alert("DOESN'T ADD SCRIPT TAG ON HEAD");
}
}
Loads scripts that depends on one another with the right order.
Based on Satyam Pathak response, but fixed the onload.
It was triggered before the script actually loaded.
const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0
const recursivelyAddScript = (script, cb) => {
const el = document.createElement('script')
el.src = script
if(count < scripts.length) {
count ++
el.onload = () => recursivelyAddScript(scripts[count])
document.body.appendChild(el)
} else {
console.log('All script loaded')
return
}
}
recursivelyAddScript(scripts[count])
Well, there are multiple ways you can include dynamic javascript,
I use this one for many of the projects.
var script = document.createElement("script")
script.type = "text/javascript";
//Chrome,Firefox, Opera, Safari 3+
script.onload = function(){
console.log("Script is loaded");
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);
You can call create a universal function which can help you to load as many javascript files as needed. There is a full tutorial about this here.
Inserting Dynamic Javascript the right way
No one mentioned it, but you can also stick the actual source code into a script tag by making a URL out of it using URL and Blob:
const jsCode = `
// JS code in here. Maybe you extracted it from some HTML string.
`
const url = URL.createObjectURL(new Blob([jsCode]))
const script = document.createElement('script')
script.src = url
URL.revokeObjectURL(url) // dispose of it when done
as for the jsCode, you may have gotten it from some HTML.
Here's a more full example of how you'd handle any number of scripts in an HTML source:
main()
async function main() {
const scriptTagOpen = /<script\b[^>]*>/g
const scriptTagClose = /<\/script\b[^>]*>/g
const scriptTagRegex = /<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/g
const response = await fetch('path/to/some.html')
const html = await response.text()
someElement.innerHTML = html
// We need to get the script tags and manually add them to DOM
// because otherwise innerHTML will not execute them.
const codes =
html
.match(scriptTagRegex)
?.map(code => code.replace(scriptTagOpen, '').replace(scriptTagClose, ''))
.map(code => URL.createObjectURL(new Blob([code]))) || []
for (const code of codes) {
const script = document.createElement('script')
script.src = code
someElement.append(script)
URL.revokeObjectURL(code)
}
}
the only way to do this is to replace document.write with your own function which will append elements to the bottom of your page. It is pretty straight forward with jQuery:
document.write = function(htmlToWrite) {
$(htmlToWrite).appendTo('body');
}
If you have html coming to document.write in chunks like the question example you'll need to buffer the htmlToWrite segments. Maybe something like this:
document.write = (function() {
var buffer = "";
var timer;
return function(htmlPieceToWrite) {
buffer += htmlPieceToWrite;
clearTimeout(timer);
timer = setTimeout(function() {
$(buffer).appendTo('body');
buffer = "";
}, 0)
}
})()
I tried it by recursively appending each script
Note If your scripts are dependent one after other, then position will need to be in sync.
Major Dependency should be in last in array so that initial scripts can use it
const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0
const recursivelyAddScript = (script, cb) => {
const el = document.createElement('script')
el.src = script
if(count < scripts.length) {
count ++
el.onload = recursivelyAddScript(scripts[count])
document.body.appendChild(el)
} else {
console.log('All script loaded')
return
}
}
recursivelyAddScript(scripts[count])
Here is a minified snippet, same code as Google Analytics and Facebook Pixel uses:
!function(e,s,t){(t=e.createElement(s)).async=!0,t.src="https://example.com/foo.js",(e=e.getElementsByTagName(s)[0]).parentNode.insertBefore(t,e)}(document,"script");
Replace https://example.com/foo.js with your script path.
window.addEventListener("load", init);
const loadScript = async (url) => {
const response = await fetch(url);
const script = await response.text();
eval(script);
}
function init() {
const wistiaVideo = document.querySelector(".wistia_embed");
if ("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype) {
let lazyVideoObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
setTimeout(() => loadScript("//fast.wistia.com/assets/external/E-v1.js"), 1000);
lazyVideoObserver.unobserve(entry.target);
console.log("E-v1.js script loaded from fast.wistia.com");
}
});
});
lazyVideoObserver.observe(wistiaVideo);
}
}
<div style="height: 150vh; background-color: #f7f7f7;"></div>
<h1>Wistia Video!</h1>
<div class="wistia_embed wistia_async_29b0fbf547" style="width:640px;height:360px;"> </div>
<h1>Video Ended!</h1>
I would like to add to my react component a
<script>http://xxx.xxx/XX.js</script>
I know I can simply add it using JSX , what I don't know is how to use it,
for instance this script has a function called A.Sort() , how can I call it and use it from a component?
You can load the script asynchronously and access it on load.
componentDidMount() {
const script = document.createElement("script");
script.src = "/static/libs/your_script.js";
script.async = true;
script.onload = () => this.scriptLoaded();
document.body.appendChild(script);
}
It should get attached to the window.
scriptLoaded() {
window.A.sort();
}
or
scriptLoaded() {
A.sort();
}
You can include the tag in the /public/index.html, and then use the script as you use it in normal JS code, following example for if you want to use jQuery:
in your public/index.html include the following:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
And then anywhere you can use the jQuery functionality as usual:
window.$("#btn1").click(function(){
alert("Text: " + $("#test").text());
});
You can use React Helmet npm
step 1 : npm i react-helmet
step 2 :
<Helmet>
<script src="/path/to/resource.js" type="text/javascript" />
</Helmet>
Sometimes we need to work with external js libraries in such cases we need to insert script tags into components, but in react we use jsx, so we can’t add script tags directly just like how we add in HTML.
In this example, we will see how to load an external script file into a head, body elements, or component.
componentDidMount() {
const script = document.createElement("script");
script.async = true;
script.src = "https://some-scripturl.js";
script.onload = () => this.scriptLoaded();
//For head
document.head.appendChild(script);
// For body
document.body.appendChild(script);
// For component
this.div.appendChild(script);
}
You can either modify your index.html file (if you are using one) by adding the required script.
Alternatively, if you can't edit it or you are not using it, there's a bunch of add-ons that solve this, for example react-load-script
After adding this script into your index.html
<script>http://xxx.xxx/XX.js</script>
you might check the available functions if you console.log(window) in App.js (or, wherever you want). Once you check the exact function, then you can use it like
window.A.sort();
I think this could be the simplest way. Just remember that you have to write 'window.' on the left side of your function.
If you want to import script in multiple components, then you can create your own custom hook that allows you to insert script in desired component:
import { useEffect } from 'react'
const importScript = src => {
useEffect(() => {
const script = document.createElement('script')
script.src = src
script.async = true
document.body.appendChild(script)
return () => {
document.body.removeChild(script)
}
}, [src])
}
export default importScript
Using it on your desired component:
import importScript from 'import-path'
const DesiredComponent = props => {
importScript("/path/to/resource")
// ... rest of the code
}
A hooks version.
import * as React from "react";
function loadError(onError) {
console.error(`Failed ${onError.target.src} didn't load correctly`);
}
function External() {
React.useEffect(() => {
const LoadExternalScript = () => {
const externalScript = document.createElement("script");
externalScript.onerror = loadError;
externalScript.id = "external";
externalScript.async = true;
externalScript.type = "text/javascript";
externalScript.setAttribute("crossorigin", "anonymous");
document.body.appendChild(externalScript);
externalScript.src = `https://externalurl.example.com/external.js?key=9393ABCDEFGH`;
};
LoadExternalScript();
}, []);
return <></>;
}
export default External;
I would like to add to my react component a
<script>http://xxx.xxx/XX.js</script>
I know I can simply add it using JSX , what I don't know is how to use it,
for instance this script has a function called A.Sort() , how can I call it and use it from a component?
You can load the script asynchronously and access it on load.
componentDidMount() {
const script = document.createElement("script");
script.src = "/static/libs/your_script.js";
script.async = true;
script.onload = () => this.scriptLoaded();
document.body.appendChild(script);
}
It should get attached to the window.
scriptLoaded() {
window.A.sort();
}
or
scriptLoaded() {
A.sort();
}
You can include the tag in the /public/index.html, and then use the script as you use it in normal JS code, following example for if you want to use jQuery:
in your public/index.html include the following:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
And then anywhere you can use the jQuery functionality as usual:
window.$("#btn1").click(function(){
alert("Text: " + $("#test").text());
});
You can use React Helmet npm
step 1 : npm i react-helmet
step 2 :
<Helmet>
<script src="/path/to/resource.js" type="text/javascript" />
</Helmet>
Sometimes we need to work with external js libraries in such cases we need to insert script tags into components, but in react we use jsx, so we can’t add script tags directly just like how we add in HTML.
In this example, we will see how to load an external script file into a head, body elements, or component.
componentDidMount() {
const script = document.createElement("script");
script.async = true;
script.src = "https://some-scripturl.js";
script.onload = () => this.scriptLoaded();
//For head
document.head.appendChild(script);
// For body
document.body.appendChild(script);
// For component
this.div.appendChild(script);
}
You can either modify your index.html file (if you are using one) by adding the required script.
Alternatively, if you can't edit it or you are not using it, there's a bunch of add-ons that solve this, for example react-load-script
After adding this script into your index.html
<script>http://xxx.xxx/XX.js</script>
you might check the available functions if you console.log(window) in App.js (or, wherever you want). Once you check the exact function, then you can use it like
window.A.sort();
I think this could be the simplest way. Just remember that you have to write 'window.' on the left side of your function.
If you want to import script in multiple components, then you can create your own custom hook that allows you to insert script in desired component:
import { useEffect } from 'react'
const importScript = src => {
useEffect(() => {
const script = document.createElement('script')
script.src = src
script.async = true
document.body.appendChild(script)
return () => {
document.body.removeChild(script)
}
}, [src])
}
export default importScript
Using it on your desired component:
import importScript from 'import-path'
const DesiredComponent = props => {
importScript("/path/to/resource")
// ... rest of the code
}
A hooks version.
import * as React from "react";
function loadError(onError) {
console.error(`Failed ${onError.target.src} didn't load correctly`);
}
function External() {
React.useEffect(() => {
const LoadExternalScript = () => {
const externalScript = document.createElement("script");
externalScript.onerror = loadError;
externalScript.id = "external";
externalScript.async = true;
externalScript.type = "text/javascript";
externalScript.setAttribute("crossorigin", "anonymous");
document.body.appendChild(externalScript);
externalScript.src = `https://externalurl.example.com/external.js?key=9393ABCDEFGH`;
};
LoadExternalScript();
}, []);
return <></>;
}
export default External;
I want to dynamically include a script tag in a webpage however I have no control of it's src so src="source.js" may look like this.
document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')
Now ordinarily putting
<script type="text/javascript" src="source.js"></script>
In the head works fine but is there any other way I can add source.js dynamically using something like innerHTML?
jsfiddle of what i've tried
var my_awesome_script = document.createElement('script');
my_awesome_script.setAttribute('src','http://example.com/site.js');
document.head.appendChild(my_awesome_script);
You can use the document.createElement() function like this:
function addScript( src ) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
document.body.appendChild( s );
}
There is the onload function, that could be called when the script has loaded successfully:
function addScript( src, callback ) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
s.onload=callback;
document.body.appendChild( s );
}
It's almost a decade later and nobody bothers to write the Promise version, so here is mine (based on this awnser):
function addScript(src) {
return new Promise((resolve, reject) => {
const s = document.createElement('script');
s.setAttribute('src', src);
s.addEventListener('load', resolve);
s.addEventListener('error', reject);
document.body.appendChild(s);
});
}
Usage
try {
await addScript('https://api.stackexchange.com/js/2.0/all.js');
// do something after it was loaded
} catch (e) {
console.log(e);
}
a nice little script I wrote to load multiple scripts:
function scriptLoader(scripts, callback) {
var count = scripts.length;
function urlCallback(url) {
return function () {
console.log(url + ' was loaded (' + --count + ' more scripts remaining).');
if (count < 1) {
callback();
}
};
}
function loadScript(url) {
var s = document.createElement('script');
s.setAttribute('src', url);
s.onload = urlCallback(url);
document.head.appendChild(s);
}
for (var script of scripts) {
loadScript(script);
}
};
usage:
scriptLoader(['a.js','b.js'], function() {
// use code from a.js or b.js
});
When scripts are loaded asynchronously they cannot call document.write. The calls will simply be ignored and a warning will be written to the console.
You can use the following code to load the script dynamically:
var scriptElm = document.createElement('script');
scriptElm.src = 'source.js';
document.body.appendChild(scriptElm);
This approach works well only when your source belongs to a separate file.
But if you have source code as inline functions which you want to load dynamically and want to add other attributes to the script tag, e.g. class, type, etc., then the following snippet would help you:
var scriptElm = document.createElement('script');
scriptElm.setAttribute('class', 'class-name');
var inlineCode = document.createTextNode('alert("hello world")');
scriptElm.appendChild(inlineCode);
document.body.appendChild(scriptElm);
You can try following code snippet.
function addScript(attribute, text, callback) {
var s = document.createElement('script');
for (var attr in attribute) {
s.setAttribute(attr, attribute[attr] ? attribute[attr] : null)
}
s.innerHTML = text;
s.onload = callback;
document.body.appendChild(s);
}
addScript({
src: 'https://www.google.com',
type: 'text/javascript',
async: null
}, '<div>innerHTML</div>', function(){});
A one-liner (no essential difference to the answers above though):
document.body.appendChild(document.createElement('script')).src = 'source.js';
This Is Work For Me.
You Can Check It.
var script_tag = document.createElement('script');
script_tag.setAttribute('src','https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js');
document.head.appendChild(script_tag);
window.onload = function() {
if (window.jQuery) {
// jQuery is loaded
alert("ADD SCRIPT TAG ON HEAD!");
} else {
// jQuery is not loaded
alert("DOESN'T ADD SCRIPT TAG ON HEAD");
}
}
Loads scripts that depends on one another with the right order.
Based on Satyam Pathak response, but fixed the onload.
It was triggered before the script actually loaded.
const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0
const recursivelyAddScript = (script, cb) => {
const el = document.createElement('script')
el.src = script
if(count < scripts.length) {
count ++
el.onload = () => recursivelyAddScript(scripts[count])
document.body.appendChild(el)
} else {
console.log('All script loaded')
return
}
}
recursivelyAddScript(scripts[count])
Well, there are multiple ways you can include dynamic javascript,
I use this one for many of the projects.
var script = document.createElement("script")
script.type = "text/javascript";
//Chrome,Firefox, Opera, Safari 3+
script.onload = function(){
console.log("Script is loaded");
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);
You can call create a universal function which can help you to load as many javascript files as needed. There is a full tutorial about this here.
Inserting Dynamic Javascript the right way
No one mentioned it, but you can also stick the actual source code into a script tag by making a URL out of it using URL and Blob:
const jsCode = `
// JS code in here. Maybe you extracted it from some HTML string.
`
const url = URL.createObjectURL(new Blob([jsCode]))
const script = document.createElement('script')
script.src = url
URL.revokeObjectURL(url) // dispose of it when done
as for the jsCode, you may have gotten it from some HTML.
Here's a more full example of how you'd handle any number of scripts in an HTML source:
main()
async function main() {
const scriptTagOpen = /<script\b[^>]*>/g
const scriptTagClose = /<\/script\b[^>]*>/g
const scriptTagRegex = /<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/g
const response = await fetch('path/to/some.html')
const html = await response.text()
someElement.innerHTML = html
// We need to get the script tags and manually add them to DOM
// because otherwise innerHTML will not execute them.
const codes =
html
.match(scriptTagRegex)
?.map(code => code.replace(scriptTagOpen, '').replace(scriptTagClose, ''))
.map(code => URL.createObjectURL(new Blob([code]))) || []
for (const code of codes) {
const script = document.createElement('script')
script.src = code
someElement.append(script)
URL.revokeObjectURL(code)
}
}
the only way to do this is to replace document.write with your own function which will append elements to the bottom of your page. It is pretty straight forward with jQuery:
document.write = function(htmlToWrite) {
$(htmlToWrite).appendTo('body');
}
If you have html coming to document.write in chunks like the question example you'll need to buffer the htmlToWrite segments. Maybe something like this:
document.write = (function() {
var buffer = "";
var timer;
return function(htmlPieceToWrite) {
buffer += htmlPieceToWrite;
clearTimeout(timer);
timer = setTimeout(function() {
$(buffer).appendTo('body');
buffer = "";
}, 0)
}
})()
I tried it by recursively appending each script
Note If your scripts are dependent one after other, then position will need to be in sync.
Major Dependency should be in last in array so that initial scripts can use it
const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0
const recursivelyAddScript = (script, cb) => {
const el = document.createElement('script')
el.src = script
if(count < scripts.length) {
count ++
el.onload = recursivelyAddScript(scripts[count])
document.body.appendChild(el)
} else {
console.log('All script loaded')
return
}
}
recursivelyAddScript(scripts[count])
Here is a minified snippet, same code as Google Analytics and Facebook Pixel uses:
!function(e,s,t){(t=e.createElement(s)).async=!0,t.src="https://example.com/foo.js",(e=e.getElementsByTagName(s)[0]).parentNode.insertBefore(t,e)}(document,"script");
Replace https://example.com/foo.js with your script path.
window.addEventListener("load", init);
const loadScript = async (url) => {
const response = await fetch(url);
const script = await response.text();
eval(script);
}
function init() {
const wistiaVideo = document.querySelector(".wistia_embed");
if ("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype) {
let lazyVideoObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
setTimeout(() => loadScript("//fast.wistia.com/assets/external/E-v1.js"), 1000);
lazyVideoObserver.unobserve(entry.target);
console.log("E-v1.js script loaded from fast.wistia.com");
}
});
});
lazyVideoObserver.observe(wistiaVideo);
}
}
<div style="height: 150vh; background-color: #f7f7f7;"></div>
<h1>Wistia Video!</h1>
<div class="wistia_embed wistia_async_29b0fbf547" style="width:640px;height:360px;"> </div>
<h1>Video Ended!</h1>