Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Dave Ferguson and Simon Free and Tim Cunningham and Jason Dean
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Dave Ferguson@dfgrumpy ) , Simon Free@simonfree ) , Tim Cunningham@TimCunningham71 ) , and Jason Dean@JasonPDean )

Dynamically Creating Script Tags With Umbrella JS

By on

In the process of replacing jQuery with Umbrella JS as my DOM (Document Object Model) abstraction layer, I ran into a small quirky behavior. It seems that if I created a <script> element using the Umbrella JS constructor, the JavaScript code within the script tag would be inert if the tag was created as an HTML snippet. However, if I created the tag using document.createElement(), then the JavaScript content would be executed when added to the DOM.

To this in action, let's generate two <script> tags, one using either approach, append them to the body tag and see what we get in the console. Here's the JavaScript code:

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>
		Dynamically Creating Script Tags With Umbrella JS
	</title>
</head>
<body>

	<h1>
		Dynamically Creating Script Tags With Umbrella JS
	</h1>

	<!-- Load scripts. -->
	<script type="text/javascript" src="../../vendor/umbrella/3.3.0/umbrella-3.3.0.min.js"></script>
	<!--
		CAUTION: I'm including a custom jQuery-compatibility file that adds some methods
		to the Umbrella JS prototype in order to bring its API closer to the jQuery API.
	-->
	<script type="text/javascript" src="../../vendor/umbrella/jquery-compat.js"></script>
	<script type="text/javascript">

		// In the first attempt, we're creating a Script tag by passing-in an HTML
		// snippet to the Umbrella JS constructor.
		u( "<script>" )
			.attr( "type", "text/javascript" )
			.text( "console.log( 'Hello from HTML snippet!' )" )
			.appendTo( document.body )
		;

		// In the second attempt, we're explicitly creating a native Script element and
		// then passing that node into the Umbrella JS constructor.
		u( document.createElement( "script" ) )
			.attr( "type", "text/javascript" )
			.text( "console.log( 'Hello from native element!' )" )
			.appendTo( document.body )
		;

	</script>

</body>
</html>

As you can see, we're using the following two Umbrella JS constructor invocations to build up script tags:

  • u( "<script>" )
  • u( document.createElement( "script" ) )

... then we're setting the textContent values and appending them to the DOM. And, when we execute this code, we get the following browser output:

Console log showing that only the JavaScript in the native script element was executed.

As you can see, both <script> tags were created and injected into the DOM. However, the one created as an HTML snippet appears to be inert. Only the one created using document.createElement() had its JavaScript code executed.

To be clear, this has nothing to do with the fact that I'm setting the textContent property (via .text()) - the same inert behavior would be observed if I were setting the src attribute in order to load a remote JavaScript file. If created using an HTML snippet, no remote script file will be loaded.

A few years ago, I ran into a similar problem with jQuery as well. In that post, jQuery wouldn't execute Script tags created with a <script> HTML snippet. So, my guess is that this is not a jQuery / Umbrella JS issue but rather a low-level DOM issue.

But hey, at least there's a really easy work-around using native DOM node creation.

Want to use code from this post? Check out the license.

Reader Comments

Post A Comment — I'd Love To Hear From You!

Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.