A 16-line hack to make the JS DOM API a tad more humane.



…absolutely amazing. I’ve yet to find a smaller and yet more astounding example of how you can encapsulate functionality within JavaScript and create brand new APIs on the fly. Ian Smith, 3 must read JavaScript articles

Web pages are written in HTML WP but as they have become more and more complex, they now tend to be written, clientside, through Javascript WP, which can manipulate and insert HTML. Google Images, for instance, uses Javascript to write the HTML that displays your image results.

Yes, it’s roundabout, but it’s due to the nature of the languages: Javascript does stuff, HTML displays stuff. When you want the browser to do things (instead of merely displaying dumbly what it receives) and when these things themselves involve a lot of displaying, you end up writing HTML through Javascript.

It’s a little like writing French through English (André went to Marie and said: “Bonjour! Ça va, ma chérie?”) and just as frustrating, particularly because you sometimes have to narrate whole scenes in French (pidgin tends to be painfully verbose) and your English self is left completely in the dark — so you end up naming things in both French and English and it gets as ugly as you can imagine.

HyperScript is a bizarre and quixotic attempt to write French in English; that is, HTML in Javascript. Basically, you do what went on in the Norman conquest of England WP: you anglicize as many French words as you can; that is, you turn into Javascript as many HTML words as you can.

The lark itself takes gratefully (and rather surpisingly) only 16 paltry lines of Javascript code (highlighting thanks to Mark “Tarquin” Wilton-Jones.):

function each ( a , f )) { for ( var i = 0 , l = a . length ; i < l ; i + + )) f ( a [ i ])) }; each (' a big blockquote br b center code div em form h1 h2 h3 h4 h5 h6 hr img iframe input i li ol option pre p script select small span strong style sub sup table tbody td textarea tr ul u '. split (' ')), function ( label ){ window [ label ] = function (){ var tag = document . createElement ( label )); each ( arguments , function ( arg ){ if ( arg . nodeType )) tag . appendChild ( arg )); else if ( typeof arg = = ' string ' | | typeof arg = = ' number ')) tag . innerHTML + = arg ; else for ( var attr in arg ){ if ( attr = = ' style ')) for ( var sty in arg [ attr ])) tag [ attr ][ sty ] = arg [ attr ][ sty ]; else tag [ attr ] = arg [ attr ]; }; })); return tag ; }; }));

div(({style:{background:'lavender', padding:'10px', fontSize:'130%', textAlign:'center'}}, b ('Hello ') , span ('world', {className:'pink'}) , '!', br () , br () , table(({style:{margin:'0 auto', width:'300px'}}, tbody(( tr(( td(({style:{background:'#ccc'}}, a ({href:'http://javascript.crockford.com/'}, 'A link!') )), td(({style:{background:'#fff'}}, img ({src:'/images/blog/logos/elzr.gif'}) )) )) )) )) ))





Test Area:

and you can play with it right here, right now:

does it work now?

The translation between HTML and Hyperscript is straightforward, where you would have written

<b>Hello world!</b> ,

you now write,

b(‘Hello World!’).

Instead of

<em style=“background-color:yellow”>Hello world!</em>,

now it’s,

em({style:{backgroundColor:’yellow’}},‘Hello World!’).

And so on.

HTML in a Javascript syntax. Enjoy!