Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Matt Vickers and Christian Ready
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Matt Vickers Christian Ready

Dynamically Creating Script Tags With Umbrella JS

By
Published in

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!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel