Easy Mashups With Parameterized Script Tags

While working with Rojo recently I was asked for a way to pass parameterized values into a script tag that would be used by third parties. There are several standard ways to do this (using global variables in a script block before you include the script; passing them in as query parameters on the script tag and have the values inserted by a server-side script; passing them in on the page location itself and have the JavaScript inspect its location), but I've been exploring a cleaner way that is much easier to read and is easier to write. Imagine if you could invoke a Yahoo Maps mashup this way from your web page:

<script longitude="200" latitude="500" src="http://www.yahoo.com/maps.js"></script>

I threw together a simple testing script and tested it cross browser and cross platform. This script tests being able to retrieve script tags by their ID, retrieving all script tags in the document, enumerating over them, and printing out two custom attribute values, "customAttribute1" and "customAttribute2". I tested the following browsers and they all worked: Firefox 1.4/Windows, IE 6/Windows, Safari 2.0/Mac, Firefox 1.5/Mac, and Opera 8.51.

The script is pretty straightforward:


test.html:
<html>
<head>
<script id="testScript"
customAttribute1="hello world"
customAttribute2="goodbye world"
src="test.js"></script>
</head>
<html>

test.js:
var byId = document.getElementById("testScript");
alert("byId="+byId);
var allScripts = document.getElementsByTagName("script");
alert("allScripts="+allScripts);
alert("allScripts.length="+allScripts.length);
var testScript = allScripts[0];
alert("testScript="+testScript);
var customAttribute1 = testScript.getAttribute("customAttribute1");
alert("customAttribute1="+customAttribute1);
var customAttribute2 = testScript.getAttribute("customAttribute2");
alert("customAttribute2="+customAttribute2);
This technique should help sites that want to turn themselves into a collection of decentralized web services that can be invoked and embedded; it can also help AJAX/DHTML libraries to easily pass in parameterized values, such as in Dojo. This can replace Dojo's djConfig static block, simply passing the values in when you pull dojo.js in:

<script src="dojo.js" dojoBase="." preventBackButtonFix="true"></script>

Comments

While it's a nice technique, and one very much in tune with what I believe has always been a basic idea of the extensibility of the SGML/XML families of markup languages, doesn't this also break page well-formedness with HTML validation services?

Don't get me wrong; in itself, that isn't a problem, but I believe the consequences are that browsers may revert to forms of quirks mode, which can wreak all sorts of havoc.

Last time (around 2002, I think) I researched how to have pages with local extensions validate through making a document type definition of your own (importing the HTML DTD and extending it with your own sub set of attributes), there was no way of rendering pages using this DTD in standards compliance mode. I hope there are better answers for that question today, but I haven't heard any.
Brad Neuberg said…
Hi Johan; I believe in techniques that make DHTML development more maintainable and readable, at the expense of validation services, as long as they work cross browser and cross platform. See http://codinginparadise.org/weblog/2005/08/xhtml-considered-harmful.html for a short opinion piece on this.
David said…
Adding custom attributes does not break the well-formedness of a page.

I believe the consequences are that browsers may revert to forms of quirks mode

Render mode is usually determined by DOCTYPE. Browsers aren't actually validating pages as they come in, that'd be expensive and doesn't buy you anything. The only thing they look for is that the page is valid XML if you send it as text/xml or similar. Adding custom attributes should have no negative effect.