When I need to pass config options to an external JavaScript code included using <script>
tag I have
several options. The simplest way is to create a global config object
1 | <script> |
1 | // foo.js |
I do not like this approach, unless there is a large and complicated configuration object. This approach
pollutes the global environment, even when I delete the fooConfig
inside foo.js
after I am done reading
the options.
My second approach is to register a function that accepts the settings first, and then call it with the actual config object
1 | <script src="foo.js"></script> |
This approach separates the configuration from the execution step, but pollutes the global environment, and might not
work correctly with scripts loaded using async
flag.
The third approach I like is inspired by AngularJs widgets.
<my-widget-foo bar="baz"></my-widget-foo>
I can pass the config values as script tag's attributes
<script src="foo.js" bar="baz" name="foo"></script>
The attribute name="foo"
is necessary to make sure we grab the correct options, even if the script
tag is loaded asynchronously. I prefer using the attribute values to
the query arguments (src="foo?bar=baz&...
) for clarity.
Inside the script we can grab attributes for a tags with the given name.
Because getElementsByTagName
returns NodeList we need to apply Array.prototype.some
in order
to conveniently iterate over the list.
1 | function getScriptAttributes(name) { |
The namedNodeMapToObject
is a utility function that converts from a NamedNodeMap
structure to a plain object
1 | function namedNodeMapToObject(map) { |
Finally, I placed the above code into script-attributes repository. You can include a small script and get the arguments like this
1 | <script src="script-attributes.js"></script> |
1 | var options = scriptAttributes('foo'); |