<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BLARGH!! for the people &#187; javascript</title>
	<atom:link href="http://blargh.tommymontgomery.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blargh.tommymontgomery.com</link>
	<description>It&#039;s time to bring forth the rhythm and the rhyme</description>
	<lastBuildDate>Fri, 09 Jul 2010 04:03:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Refresh Current Page in JavaScript</title>
		<link>http://blargh.tommymontgomery.com/2010/05/refresh-current-page-in-javascript/</link>
		<comments>http://blargh.tommymontgomery.com/2010/05/refresh-current-page-in-javascript/#comments</comments>
		<pubDate>Sun, 09 May 2010 23:55:26 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=513</guid>
		<description><![CDATA[It&#8217;s more annoying than it sounds. You could do the classic:

window.location = window.location; //refresh lol!

But you&#8217;ll get screwed if there is a fragment, like, say, http://example.com/index.html#section1. The page won&#8217;t refresh. Or rather, it will, but browsers won&#8217;t send a request to the server if the url contains a fragment. It will just try to navigate [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s more annoying than it sounds. You could do the classic:</p>
<pre class="brush: jscript;">
window.location = window.location; //refresh lol!
</pre>
<p>But you&#8217;ll get screwed if there is a <a href="http://www.w3.org/TR/WD-html40-970708/htmlweb.html#h-4.1.1">fragment</a>, like, say, <kbd>http://example.com/index.html#section1</kbd>. The page won&#8217;t refresh. Or rather, it will, but browsers won&#8217;t send a request to the server if the url contains a fragment. It will just try to navigate to that fragment within the document.</p>
<p>Solution: be awesome.</p>
<pre class="brush: jscript;">
(function(){
  var refreshCookie = &quot;mysite.refreshFragment&quot;;

  var refresh = function() {
    var url = window.location.href;
    var fragmentPosition = url.lastIndexOf(&quot;#&quot;);
    if (fragmentPosition &gt;= 0) {
      if (fragmentPosition !== url.length - 1) {
        $.cookie(refreshCookie, url.substring(fragmentPosition + 1)); //store the fragment in a cookie
      }
      url = url.substring(0, fragmentPosition);
    }
    window.location.href = url;
  };

  var applyFragmentFromCookie = function() {
    var fragment = $.cookie(refreshCookie);
    if (fragment !== null) {
      window.location.href += &quot;#&quot; + fragment;
      $.cookie(refreshCookie, null); //delete cookie
    }
  };

  //reapply the fragment (if necessary) when the page is loaded
  $(document).ready(applyFragmentFromCookie);

  //expose to the public (you would of course properly namespace this, right?)
  window.refresh = refresh;
}());

//then, when you wanted to refresh the page...
refresh();
</pre>
<p>I use the <a href="http://plugins.jquery.com/project/cookie">jQuery cookie plugin</a>, because all the kids nowadays are using jQuery. Substitute your own <a href="http://www.dustindiaz.com/top-ten-javascript/">cookie handling framework</a>, or roll your own (I&#8217;ve done it, it&#8217;s not enjoyable).</p>
<p><a href="http://tmont.com/experiments/javascript-refresh/">See it in action.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2010/05/refresh-current-page-in-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get Computed Style in JavaScript</title>
		<link>http://blargh.tommymontgomery.com/2010/04/get-computed-style-in-javascript/</link>
		<comments>http://blargh.tommymontgomery.com/2010/04/get-computed-style-in-javascript/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 10:25:15 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=476</guid>
		<description><![CDATA[The computed style of an element incorporates external CSS (via stylesheets), inline styles and styles prescribed via JavaScript. It&#8217;s most commonly used to get the default style of an element if it&#8217;s not specifically assigned via styles, i.e. the default style that the browser gives an element. It&#8217;s a very undocumented part of JavaScript engines, [...]]]></description>
			<content:encoded><![CDATA[<p>The computed style of an element incorporates external CSS (via stylesheets), inline styles and styles prescribed via JavaScript. It&#8217;s most commonly used to get the default style of an element if it&#8217;s not specifically assigned via styles, i.e. the default style that the browser gives an element. It&#8217;s a very undocumented part of JavaScript engines, and, of course, there are multiple implementations. For more details, read <a href="http://blog.stchur.com/2006/06/21/css-computed-style/">this blog post</a>.</p>
<p>For my <a href="http://linkurious.com/">Linkurious</a> project, I needed to get the computed style of an element in a cross browser way. I came up with an implementation that works in every version of every browser (within reason, the <a href="http://www.armory.com/~spectre/cwi/hl/">C64</a> is not supported), and is easy to use.</p>
<p>I&#8217;ll leave the details of how it works as an exercise to the reader. I will say that this is a good example of how to use a closure to improve the efficiency of a function. Notice that the cross-browser garbage is only executed once, not on each call.</p>
<pre class="brush: jscript;">
//must be executed on or after the domready event, since it (may) require document.body to be non-null
var getComputedStyle = function() {
  var func = null;
  if (document.defaultView &amp;&amp; document.defaultView.getComputedStyle) {
    func = document.defaultView.getComputedStyle;
  } else if (typeof(document.body.currentStyle) !== &quot;undefined&quot;) {
    func = function(element, anything) {
      return element[&quot;currentStyle&quot;];
    };
  }

  return function(element, style) {
    return func(element, null)[style];
  }
}();

//and use like so:
getComputedStyle(document.getElementById(&quot;foo&quot;), &quot;display&quot;); //might return &quot;inline-block&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2010/04/get-computed-style-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>top != self and fun with the Tokelauans</title>
		<link>http://blargh.tommymontgomery.com/2010/01/top-self-and-fun-with-the-tokelauans/</link>
		<comments>http://blargh.tommymontgomery.com/2010/01/top-self-and-fun-with-the-tokelauans/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 09:42:04 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[rants]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=388</guid>
		<description><![CDATA[I noticed recently that THE GREATEST SITE IN THE WORLD had a new referrer. I checked it out, and saw this:

A touch of JavaScript, and now they see this:

Just say NO to frames. And kiwis.
]]></description>
			<content:encoded><![CDATA[<p>I noticed recently that <a href="http://urmomisugly.com/">THE GREATEST SITE IN THE WORLD</a> had a new referrer. I checked it out, and saw this:</p>
<p><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2010/01/kiwifail.png" alt="kiwifail" title="kiwifail" width="634" height="316" class="aligncenter size-full wp-image-389" /></p>
<p>A touch of JavaScript, and now they see this:</p>
<p><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2010/01/kiwifail2.png" alt="kiwifail2" title="kiwifail2" width="382" height="121" class="aligncenter size-full wp-image-390" /></p>
<p><a href="http://www.buduglydesign.com/frame9806/hateframe.html">Just say NO to frames</a>. And kiwis.</p>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2010/01/top-self-and-fun-with-the-tokelauans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intro to Functional Programming via JavaScript</title>
		<link>http://blargh.tommymontgomery.com/2010/01/intro-to-functional-programming-via-javascript/</link>
		<comments>http://blargh.tommymontgomery.com/2010/01/intro-to-functional-programming-via-javascript/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 09:03:03 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=367</guid>
		<description><![CDATA[This is purely an academic exercise. Adam contacted recently with a link to a blog post on implementing the Y-combinator in JavaScript. There were a whole bunch of words that sound smart, such as

Recursion
Fixed point
Y-combinator
Memoization

It&#8217;s like a professor&#8217;s dream come true. I had seen the article a long time ago when I prepared a presentation [...]]]></description>
			<content:encoded><![CDATA[<p>This is purely an academic exercise. <a href="http://adam.yanalunas.com/blog/">Adam</a> contacted recently with a link to a <a href="http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/">blog post</a> on implementing the Y-combinator in JavaScript. There were a whole bunch of words that sound smart, such as</p>
<ol>
<li>Recursion</li>
<li>Fixed point</li>
<li>Y-combinator</li>
<li>Memoization</li>
</ol>
<p>It&#8217;s like a professor&#8217;s dream come true. I had seen the article a long time ago when I prepared a presentation for work about functional programming. Basically, it was an introduction to functional programming, and to help myself learn, I decided to take the extremely low-level paradigms in functional programming and implement them. JavaScript seemed like the natural language choice, since of the three languages I know pretty well (PHP, JavaScript, C#), it was the only one that supported closures in a convenient way. Sold.</p>
<p>Anyway, here&#8217;s the presentation. You just might learn something.</p>
<object width="500" height="410"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=functionalprogramming-100102024238-phpapp01"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=functionalprogramming-100102024238-phpapp01"  type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="410"></embed></object><!-- ysttest:Array
(
    [id] => 2814937&#038;doc=functionalprogramming-100102024238-phpapp01&#038;w=500
)
-->
<p>Reference articles:</p>
<ul>
<li><a href="http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/">Implementation of Recursive Fixed Point Y-Combinator in JavaScript for Memoization</a> (it&#8217;s a mouthful)</li>
<li><a href="http://uxul.wordpress.com/2009/03/02/generating-church-numbers-with-javascript/">Generating Church Numbers With JavaScript</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2010/01/intro-to-functional-programming-via-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Arc Challenge: PHP and JavaScript</title>
		<link>http://blargh.tommymontgomery.com/2009/12/the-arc-challenge-php-and-javascript/</link>
		<comments>http://blargh.tommymontgomery.com/2009/12/the-arc-challenge-php-and-javascript/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 00:17:05 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=321</guid>
		<description><![CDATA[Take the Arc Challenge. For the lazy, here is the problem:
Write a program that causes the url said (e.g. http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying &#8220;click here.&#8221; When that is clicked [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.paulgraham.com/arcchallenge.html">Take the Arc Challenge</a>. For the lazy, here is the problem:</p>
<blockquote><p>Write a program that causes the url said (e.g. http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying &#8220;click here.&#8221; When that is clicked it should lead to a third page that says &#8220;you said: &#8230;&#8221; where &#8230; is whatever the user typed in the original input field. The third page must only show what the user actually typed. I.e. the value entered in the input field must not be passed in the url, or it would be possible to change the behavior of the final page by editing the url.</p>
</blockquote>
<p>I ignored the part about what the URL has to be, because that would just be annoying. The point of Arc is to write things in the most efficient way possible, and the whole language is built around helping you do that. The point of this problem is to illustrate that Arc does this very well.</p>
<p>In Arc, a solution looks like this:</p>
<pre class="brush: plain;">
(defop said req
  (aform [onlink &quot;click here&quot; (pr &quot;you said: &quot; (arg _ &quot;foo&quot;))]
    (input &quot;foo&quot;)
    (submit)))
</pre>
<p>In PHP:</p>
<pre class="brush: php;">
session_start();

if (isset($_SESSION['said'])) {
	echo 'You said: ' . htmlentities($_SESSION['said']); //prevent XSS lol
	unset($_SESSION['said']);
} else if (isset($_POST['said'])) {
	$_SESSION['said'] = $_POST['said'];
	echo '&lt;a href=&quot;&quot;&gt;Click here!&lt;/a&gt;';
} else {
	echo '&lt;form method=&quot;post&quot; action=&quot;&quot;&gt;&lt;input type=&quot;text&quot; name=&quot;said&quot;/&gt;&lt;input type=&quot;submit&quot;/&gt;&lt;/form&gt;';
}
</pre>
<p>And in JavaScript:</p>
<pre class="brush: jscript;">
function getCookie(name) {
	var cookies = document.cookie.split(&quot;;&quot;);
	for (var i = 0, len = cookies.length, cookieParts; i &lt; len; i++) {
		cookieParts = cookies[i].trim().split(&quot;=&quot;);
		if (cookieParts[0] === name) {
			return cookieParts[1];
		}
	}

	return null;
}

var said = getCookie(&quot;said&quot;), page = parseInt(getCookie(&quot;page&quot;));
if (said === null) {
	var input = document.createElement(&quot;input&quot;);
	input.type = &quot;text&quot;;
	var button = document.createElement(&quot;button&quot;);
	button.appendChild(document.createTextNode(&quot;Submit&quot;));
	button.onclick = function() {
		document.cookie = &quot;said=&quot; + input.value;
		document.cookie = &quot;page=2&quot;;
		window.location.href = window.location.href;
	}

	document.body.appendChild(input);
	document.body.appendChild(button);
	document.cookie = &quot;page=1&quot;;
} else if (page === 2) {
	document.cookie = &quot;page=3&quot;;
	var link = document.createElement(&quot;a&quot;);
	link.href = &quot;&quot;;
	link.appendChild(document.createTextNode(&quot;Click here&quot;));
	document.body.appendChild(link);
} else {
	document.body.appendChild(document.createTextNode(&quot;You said: &quot; + said));
	var expires = new Date();
	expires.setDate(expires.getDate() - 100);
	expires = expires.toGMTString();
	document.cookie = &quot;said=;expires=&quot; + expires;
	document.cookie = &quot;page=1&quot;;
}
</pre>
<p>The cookie handling could probably be more compact, but whatever; the hideousness of that is far outstretched by the hideousness of <a href="http://blargh.tommymontgomery.com/2009/11/fluent-dom-manipulation-in-javascript/">the DOM</a>. Try each of them out here:</p>
<ul>
<li><a href="http://tmont.com/experiments/arc-challenge/arc.php">PHP</a></li>
<li><a href="http://tmont.com/experiments/arc-challenge/arc.html">JavaScript</a></li>
</ul>
<p>Arc seems like a cool language. Too bad it&#8217;s based on Lisp, which means it will never get any traction in the demographics that don&#8217;t wear suspenders.</p>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2009/12/the-arc-challenge-php-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fluent DOM Manipulation in JavaScript</title>
		<link>http://blargh.tommymontgomery.com/2009/11/fluent-dom-manipulation-in-javascript/</link>
		<comments>http://blargh.tommymontgomery.com/2009/11/fluent-dom-manipulation-in-javascript/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 08:37:00 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=247</guid>
		<description><![CDATA[Everybody hates the DOM. Except me. I kinda love it. I get a little hit of endorphins every time I type all 23 characters of &#8220;document.getElementById&#8221;. I need a cigarette.
Anyway, I found myself  dissatisfied with the state of jQuery&#8217;s DOM manipulation (hint: there isn&#8217;t any). You can traverse, and do stuff with events, but [...]]]></description>
			<content:encoded><![CDATA[<p>Everybody hates the <acronym>DOM</acronym>. Except me. I kinda love it. I get a little hit of endorphins every time I type all 23 characters of &#8220;document.getElementById&#8221;. I need a cigarette.</p>
<p>Anyway, I found myself  dissatisfied with the state of <a href="http://jquery.com/">jQuery&#8217;s</a> <acronym>DOM</acronym> manipulation (hint: there isn&#8217;t any). You can traverse, and do stuff with events, but there&#8217;s no <acronym>API</acronym> to create elements and then append them to the <acronym>DOM</acronym>. So I looked at the jQuery plugins, and found <a href="http://plugins.jquery.com/project/appendDom">this</a>, which I tried and quickly learned to hate. Using JSON to create <acronym>DOM</acronym> elements is just as painful as creating them using the native <acronym>DOM</acronym> <acronym>API</acronym>.</p>
<p>So, like any good programmer, I rolled my own. And I called it <strong>FluentDom</strong> (or <strong>$dom</strong> for short). Tested in Firefox, <acronym>IE</acronym> and Opera. Licensed under the <a href="http://sam.zoy.org/wtfpl/">WTFPL</a> license.</p>
<h2>FluentDom.js</h2>
<pre class="brush: jscript;">
/**
 * Fluent DOM Manipulation
 *
 * @author  Tommy Montgomery &lt;http://tommymontgomery.com/&gt;
 * @license http://sam.zoy.org/wtfpl/
 */

(function(){

	var FluentDom = function(node) {
		return new FluentDomInternal(node);
	}

	FluentDom.create = function(tagName) {
		var f = new FluentDomInternal();
		f.create(tagName);
		return f;
	}

	var FluentDomInternal = function(node) {
		var root = node || null;

		this.fluentDom = &quot;1.0&quot;;

		this.append = function(obj) {
			if (!root || !root.appendChild) {
				throw new Error(&quot;Cannot append to a non-element&quot;);
			}

			var type = typeof(obj);
			if (type === &quot;object&quot;) {
				if (obj.fluentDom) {
					root.appendChild(obj.toDom());
				} else if (obj.nodeType) {
					root.appendChild(obj);
				} else {
					throw new Error(&quot;Invalid argument: not a DOM element or a FluentDom object&quot;);
				}
			} else if (type === &quot;string&quot; || type === &quot;number&quot;) {
				root.appendChild(document.createTextNode(obj));
			} else {
				throw new Error(&quot;Invalid argument: not an object (you gave me a &quot; + typeof(obj) + &quot;)&quot;);
			}

			return this;
		}

		this.attr = function(name, value) {
			if (!root || !root.setAttribute) {
				throw new Error(&quot;Cannot set an attribute on a non-element&quot;);
			}

			root.setAttribute(name, value);
			return this;
		}

		this.text = function(text) {
			return this.append(text);
		}

		this.create = function(tagName) {
			root = document.createElement(tagName);
			return this;
		}

		this.id = function(value) {
			return this.attr(&quot;id&quot;, value);
		}

		this.title = function(value) {
			return this.attr(&quot;title&quot;, value);
		}

		this.cls = function(value) {
			return this.attr(&quot;class&quot;, value);
		}

		this.clear = function() {
			root = null;
			return this;
		}

		this.toDom = function() {
			return root;
		}

		this.href = function(link) {
			return this.attr(&quot;href&quot;, link);
		}

	};

	window.FluentDom = window.$dom = FluentDom;

}());
</pre>
<h2>Usage</h2>
<p>Some sample usage, also showing how to integrate with jQuery:</p>
<pre class="brush: jscript;">
//let's make a list!
$dom(document.body).append(
	$dom.create(&quot;ul&quot;).id(&quot;menu&quot;).append(
		$dom.create(&quot;li&quot;).cls(&quot;menu-item&quot;).id(&quot;menu-item-1&quot;).append(
			$dom.create(&quot;a&quot;).text(&quot;List Item #1&quot;).href(&quot;#&quot;)
		)
	).append(
		$dom.create(&quot;li&quot;).cls(&quot;menu-item&quot;).id(&quot;menu-item-2&quot;).title(&quot;click to toggle&quot;).append(
			$($dom.create(&quot;a&quot;).text(&quot;List Item #2&quot;).href(&quot;#&quot;).toDom()).bind(&quot;click&quot;, function() {
				$(this).next(&quot;ul&quot;).toggle();
				return false;
			}).get(0)
		).append(
			$dom.create(&quot;ul&quot;).append(
				$dom.create(&quot;li&quot;).cls(&quot;sub-menu-item&quot;).id(&quot;menu-item-4&quot;).append(
					$dom.create(&quot;a&quot;).text(&quot;Sublist Item #1&quot;).href(&quot;#&quot;)
				)
			).append(
				$dom.create(&quot;li&quot;).cls(&quot;sub-menu-item&quot;).id(&quot;menu-item-5&quot;).append(
					$dom.create(&quot;a&quot;).text(&quot;Sublist Item #2&quot;).href(&quot;#&quot;)
				)
			).append(
				$dom.create(&quot;li&quot;).cls(&quot;sub-menu-item&quot;).id(&quot;menu-item-6&quot;).append(
					$dom.create(&quot;a&quot;).text(&quot;Sublist Item #3&quot;).href(&quot;#&quot;)
				)
			)
		)
	).append(
		$dom.create(&quot;li&quot;).cls(&quot;menu-item&quot;).id(&quot;menu-item-3&quot;).append(
			$dom.create(&quot;a&quot;).text(&quot;List Item #3&quot;).href(&quot;#&quot;)
		)
	)
);
</pre>
<p>Which creates and appends this <acronym>DOM</acronym> tree to <kbd>document.body</kbd>:</p>
<pre class="brush: xml;">
&lt;ul id=&quot;menu&quot;&gt;
  &lt;li class=&quot;menu-item&quot; id=&quot;menu-item-1&quot;&gt;&lt;a href=&quot;#&quot;&gt;List Item #1&lt;/a&gt;&lt;/li&gt;
  &lt;li class=&quot;menu-item&quot; id=&quot;menu-item-2&quot; title=&quot;click to toggle&quot;&gt;&lt;a href=&quot;#&quot;&gt;List Item #2&lt;/a&gt;
    &lt;ul&gt;
      &lt;li class=&quot;sub-menu-item&quot; id=&quot;menu-item-4&quot;&gt;&lt;a href=&quot;#&quot;&gt;Sublist Item #1&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;sub-menu-item&quot; id=&quot;menu-item-5&quot;&gt;&lt;a href=&quot;#&quot;&gt;Sublist Item #2&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;sub-menu-item&quot; id=&quot;menu-item-6&quot;&gt;&lt;a href=&quot;#&quot;&gt;Sublist Item #3&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li class=&quot;menu-item&quot; id=&quot;menu-item-3&quot;&gt;&lt;a href=&quot;#&quot;&gt;List Item #3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Admittedly, it kind of looks like a lot of code, but it&#8217;s much easier to read than if you had used the native <acronym>API</acronym>. Compare that with what the same implementation would look like if you went native:</p>
<h2>Native API Implementation</h2>
<pre class="brush: jscript;">
var ul = document.createElement(&quot;ul&quot;);
ul.id = &quot;menu&quot;;
var li = document.createElement(&quot;li&quot;);
li.className = &quot;menu-item&quot;;
li.id = &quot;menu-item-1&quot;;
var a = document.createElement(&quot;a&quot;);
a.href = &quot;#&quot;;
a.appendChild(document.createTextNode(&quot;List Item #1&quot;));
li.appendChild(a);
ul.appendChild(li);

li = document.createElement(&quot;li&quot;);
li.className = &quot;menu-item&quot;;
li.id = &quot;menu-item-2&quot;;
li.title = &quot;click to toggle&quot;;
a = document.createElement(&quot;a&quot;);
a.href = &quot;#&quot;;
a.appendChild(document.createTextNode(&quot;List Item #2&quot;));
$(a).bind(&quot;click&quot;, function() {
	$(this).next(&quot;ul&quot;).toggle();
	return false;
});
li.appendChild(a);

var subList = document.createElement(&quot;ul&quot;);

var subItem = document.createElement(&quot;li&quot;);
subItem.className = &quot;menu-item&quot;;
subItem.id = &quot;menu-item-4&quot;;
var subLink = document.createElement(&quot;a&quot;);
subLink.href = &quot;#&quot;;
subLink.appendChild(document.createTextNode(&quot;Sublist Item #1&quot;));
subItem.appendChild(subLink);
subList.appendChild(subItem);

subItem = document.createElement(&quot;li&quot;);
subItem.className = &quot;menu-item&quot;;
subItem.id = &quot;menu-item-5&quot;;
subLink = document.createElement(&quot;a&quot;);
subLink.href=&quot;#&quot;;
subLink.appendChild(document.createTextNode(&quot;Sublist Item #2&quot;));
subItem.appendChild(subLink);
subList.appendChild(subItem);

subItem = document.createElement(&quot;li&quot;);
subItem.className = &quot;menu-item&quot;;
subItem.id = &quot;menu-item-6&quot;;
subLink = document.createElement(&quot;a&quot;);
subLink.href=&quot;#&quot;;
subLink.appendChild(document.createTextNode(&quot;Sublist Item #3&quot;));
subItem.appendChild(subLink);
subList.appendChild(subItem);

li.appendChild(subList);

ul.appendChild(li);

li = document.createElement(&quot;li&quot;);
li.className = &quot;menu-item&quot;;
li.id = &quot;menu-item-3&quot;;
a = document.createElement(&quot;a&quot;);
a.href = &quot;#&quot;;
a.appendChild(document.createTextNode(&quot;List Item #3&quot;));
li.appendChild(a);
ul.appendChild(li);

document.body.appendChild(ul);
</pre>
<p>30 lines vs. 70 lines. Fluent == rad. Tell your friends.</p>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2009/11/fluent-dom-manipulation-in-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
