Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know that dynamically created script tag was executed?

I'm creating a script tag dynamically:

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.defer = true;
script.async = true;
script.text = 'some my javascript content here';
head.appendChild(script);

script.onload = function () {
    // this never get fired..
    debugger;
}

How to get notified when script was executed inside other code block? Maybe some event?

like image 351
Kosmetika Avatar asked Sep 05 '14 14:09

Kosmetika


People also ask

How do you dynamically load a script response?

We start by creating an empty <script></script> tag in the memory as script and then assign the necessary attributes to its src and the id to identify the script later. Finally, we append the script to our <body></body> tag to actually load this.

How do you execute a script tag?

The “script” tag JavaScript programs can be inserted almost anywhere into an HTML document using the <script> tag. You can run the example by clicking the “Play” button in the right-top corner of the box above. The <script> tag contains JavaScript code which is automatically executed when the browser processes the tag.

When JavaScript is executed Where is the script executed?

Whenever the JavaScript engine receives a script file, it first creates a default Execution Context known as the Global Execution Context (GEC) . The GEC is the base/default Execution Context where all JavaScript code that is not inside of a function gets executed. For every JavaScript file, there can only be one GEC.

What is a script tag?

A script tag can either include the JavaScript directly, or it can point to a URL where the script should be loaded from. Script tags are executed in the order they appear This idea should be intuitive when you read this code:

Why can’t I add dynamic script tags in HTML5?

Avoiding page load blocking was especially important as these were external resources, so they might fail or be particularly slow. It turns out that HTML5 does not allow script tags to be dynamically added using the innerHTML property. So the following will not execute and there will be no alert saying Hello World!

Why are my script tags not being interpreted?

Malformed HTML: Are you sure the script tag is actually being interpreted as a tag? Encoding issues, escaping or malformed HTML somewhere else in the document can stop this from happening. To check if this is the case, use the developer tool to see if there actually is a script tag in the DOM.

How to execute JavaScript via innerHTML without using <script> tags?

It is possible to execute JavaScript via innerHTML without using <script> tags as illustrated on MDN's innerHTML page. To dynamically add a script tag, you need to create a new script element and append it to the target element. It turns out that when scripts are loaded asynchronously they cannot call document.write.


2 Answers

I was able to get this to work by adding an ID to the script, then in the JS, manually firing the load event on that DOM element. Tested only in Chrome, will have issues in older IE according to MDN).

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.id = 'testing';
script.defer = true;
script.async = true;
script.onload = function () {
    console.log('The script is loaded');
}
script.text = ["console.log('This is from the script');",
               "var script = document.getElementById('testing');",
               "var event = new UIEvent('load');",
               "script.dispatchEvent(event);"].join('');
head.appendChild(script);

Fiddle

like image 88
pherris Avatar answered Oct 05 '22 23:10

pherris


In modern browsers you could use Mutation Observer to detect changes in an element – head in this case. Something like this:

observer = new MutationObserver(function (m) {
    // This will be fired
});
observer.observe(document.head, {childList: true});

Unfortenately this doesn't work in IE < 11, but it seems that onload is fired in IE, so you can use it for IEs.

A live demo at jsFiddle.

like image 20
Teemu Avatar answered Oct 06 '22 00:10

Teemu