<?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>Carsonified &#187; DOM</title>
	<atom:link href="http://carsonified.com/blog/category/dev/dom/feed/" rel="self" type="application/rss+xml" />
	<link>http://carsonified.com</link>
	<description></description>
	<lastBuildDate>Thu, 11 Mar 2010 19:59:56 +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>Same DOM Errors, Different Browser Interpretations</title>
		<link>http://carsonified.com/blog/dev/same-dom-errors-different-browser-interpretations/</link>
		<comments>http://carsonified.com/blog/dev/same-dom-errors-different-browser-interpretations/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 18:07:21 +0000</pubDate>
		<dc:creator>Hallvord R. M. Steen</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Features]]></category>

		<guid isPermaLink="false">http://www.thinkvitamin.com/features/dev/same-dom-errors-different-browser-fixes</guid>
		<description><![CDATA[By <strong>Hallvord R. M. Steen</strong><br />Introduction
In this article I will explore the DOM, look at some common kinds of errors that are found in the DOM and how different debugging tools can be used to find such DOM errors and make sure that the DOM is interpreted consistently across browsers. Along the way, I&#8217;ll introduce Opera Dragonfly, the new kid [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fsame-dom-errors-different-browser-interpretations%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fsame-dom-errors-different-browser-interpretations%2F" height="61" width="51" /></a></div><h2>Introduction</h2>
<p>In this article I will explore the DOM, look at some common kinds of errors that are found in the DOM and how different debugging tools can be used to find such DOM errors and make sure that the DOM is interpreted consistently across browsers. Along the way, I&rsquo;ll introduce <a href="/images/articles/dragonfly/http://www.opera.com/products/dragonfly/">Opera Dragonfly</a>, the new kid on the web development debugging block, and show how it performs.</p>
<h2>What is the DOM?</h2>
<p>When a browser receives HTML code from a website, it creates a structured overview of the HTML document. This overview is known as the DOM, and through its structure JavaScript can access the various parts of the document.</p>
<p>The &ldquo;parent&rdquo; of the DOM is the <code>document</code> object, and using its methods and properties you can reach every part of the HTML file &mdash; for example by getting the first <code>div</code> with <code>document.getElementsByTagName('div')[0]</code> or the first element in the document with <code>document.firstChild</code>.</p>
<p>The DOM is usually visualised as a tree-like structure, as seen in Figure 1. The document itself should have only one child &mdash; typically the <code>html</code> element &mdash; and that element usually has the two children <code>head</code> and <code>body</code>. Each of those can have several children, so comparing this structure to the branches of a tree is a good way to understand it.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-dom-tree.png" alt="The DOM structure of a simple HTML document as a tree" /></p>
<p class="comment">Figure 1: The DOM structure of a simple HTML document, as viewed in the DOM viewer of Opera Dragonfly as a tree structure.</p>
<p>When constructing the DOM, the quality of the markup is very important. If the markup is not valid &mdash; for example if elements are not closed correctly &mdash; it&rsquo;s much harder to create a tree structure from it. If, say, a document contains the markup <code>&lt;html&gt;&lt;head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;</code> &mdash; what is the browser going to do? Make <code>body</code> a child of <code>head</code>? Since the <code>head</code> contents are not visible in user agents, this might make the entire document disappear!</p>
<p>Because invalid markup is so common, browsers have to add lots of special rules for creating DOM structures from invalid markup. These rules differ somewhat between browsers, which means that using invalid markup dramatically increases the risk that your site will appear differently in different browsers &mdash; or even break completely in some of them.</p>
<h2>Common markup / DOM errors</h2>
<p>Below I will look at some commonly encountered DOM errors, and how browsers interpret the markup.</p>
<h3>Bad closing and nesting of elements</h3>
<p>If you look at the first example file &mdash; <a href="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-unclosed-b.htm" alt="invalid HTML example unclosed">df-dom-demo-unclosed-b.htm</a> &mdash; you will see that the markup is invalid &mdash; there are multiple problems with it, in terms of unclosed elements and incorrect nesting. If you look at the generated DOM in various web page debugger tools (see Figure 2), you will see that browsers interpret this HTML very differently.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-unclosed-b-dragonfly.png" alt="example invalid dom interpreted by Opera Dragonfly" /><br />
<img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-unclosed-b-firebug.png" alt="example invalid dom interpreted by firebug" /><br />
<img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-unclosed-b-IE-dev-toolbar.png" alt="example invalid dom interpreted by IE developer toolbar" /></p>
<p class="comment">Figure 2: From top to bottom, this shows our incorrectly closed/nested example DOM as represented in Opera Dragonfly, Mozilla Firebug, and the Internet Explorer developer toolbar.</p>
<p>The DOM inspectors reveal that these browsers handle markup errors in very different ways: Opera makes the subsequent elements children of the <code>b</code> that lacks a closing tag. Firefox adds extra <code>b</code> elements <em>between</em> the <code>p</code> tags that were not present in the markup. In IE&rsquo;s DOM we see that the text &ldquo;This text should be a link&rdquo; in fact appears to be outside the <code>a</code> tag that creates the link.</p>
<p>Because there is no standard way to handle invalid markup, none of these browsers are doing anything particularly wrong here. However, if you start adding extra styling like <code>display:none</code> to any of these elements or try cloning and manipulating them through the DOM, you&rsquo; get unexpected results across browsers because of the way the invalid markup is parsed into different DOM structures.</p>
<h3><code>body</code> inside the <code>head</code></h3>
<p>In the second sample file &mdash; <a href="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-head-contents.htm" alt="invalid HTML example head content">df-dom-demo-head-contents.htm</a> &mdash; you can see another example of invalid markup. There is a <code>div</code> element inside the <code>head</code> section. Check out this demo in various DOM explorers and you will see that all browsers move the <code>div</code> element out of the <code>head</code> and into the <code>body</code>. Figure 3 shows the different ways in which this DOM is interpreted by different browsers:</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-markup-in-head-dragonfly.png" alt="example invalid dom interpreted by Opera Dragonfly" /><br />
<img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-markup-in-head-firebug.png" alt="example invalid dom interpreted by firebug" /><br />
<img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-markup-in-head-IE-dev-toolbar.png" alt="example invalid dom interpreted by IE developer toolbar" /></p>
<p class="comment">Figure 3: From top to bottom, this shows our content in the head example&rsquo;s DOM as represented in Opera Dragonfly, Mozilla Firebug, and the Internet Explorer developer toolbar.</p>
<p>In Opera and IE, this means that any <code>head</code> content after the <code>div</code> also is moved outside of the <code>head</code> section. Also note the way Firefox has moved the <code>style</code> element from the body into the head. <code>style</code> elements are not allowed inside the <code>body</code> of course, so this is a logical thing to do, but it might confuse your script if it goes looking for the <code>style</code> element in a certain place in the tree.</p>
<h2>Using DOM inspectors for debugging</h2>
<p>As you have seen above, using DOM inspectors is a great way to <strong>see how browsers interpret the markup</strong>. This view can help explain issues you may run into when using the DOM via a JavaScript application. Some of the following examples are rather advanced, and it helps to have several of the DOM inspectors mentioned installed so that you can test the demos by yourself. The DOM inspectors used for the below analysis are Opera Dragonfly, Mozilla Firebug, the Webkit (Safari) Web Inspector, and the IE Web Developer Toolbar.</p>
<p>The third example file &mdash; <a href="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-app-meta.htm" alt="example file for cross browser DOM debugging">df-dom-demo-app-meta.htm</a> &mdash; is created by a rather unlucky web developer who has made several assumptions about how the DOM works. It turns out that he is wrong on most counts, and the app causes issues in most browsers! To start with, it doesn&#8217;t include a proper doctype in the first line. It then goes on to include a custom <code>test</code> element and a <code>meta</code> element with a custom <code>http-equiv</code> attribute value inside the <code>head</code>. Lastly, it includes a script inside the <code>body</code> that tries to read attribute values from both the <code>meta</code> and the <code>test</code> elements.</p>
<ul>
<li>
<p>In Opera it generates two exceptions. Using the Opera Dragonfly DOM explorer (see Figure 4) you can see that the reason is that the <code>test</code> and <code>meta</code> elements are not inside the <code>head</code>. When Opera sees the <code>test</code> element, it thinks the custom element name indicates the page content start, so it closes the <code>head</code> section and traps both elements outside it.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-app-meta-dragonfly.png" alt="the debugging example in dragonfly" /></p>
<p class="comment">Figure 4: Opera Dragonfly shows that Opera has trapped the two rogue elements outside the <code>head</code>. Hence, when the script looks for them inside the <code>head</code> section it can&#8217;t find them and throws exceptions.</p>
</li>
<li>
<p>In Firefox (see Figure 5), you will get the odd output message &ldquo;name of bar attribute is _moz-userdefined&rdquo; and sure enough, with Firebug&#8217;s DOM explorer you will see that Firefox added a <code>_moz-userdefined</code> attribute to the <code>test</code> element.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-app-meta-firebug.png" alt="the debugging example in firebug" /></p>
<p class="comment">Figure 5: Firebug shows that Firefox has returned an error message and added an attribute to mark the <code>test</code> element as undefined in HTML. Since the script reads the first attribute from the element, it sees the <code>_moz-userdefined</code> attribute instead of what we expected.</p>
</li>
<li>
<p>In WebKit you get one exception (see Figure 6). Like Opera, it moves the <code>test</code> element out of <code>head</code>. Unlike Opera, it appends the element to <code>body</code>, and it doesn&#8217;t move the <code>meta</code> element.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-markup-in-head-webkit-inspector.png" alt="the debugging example in webkit" /></p>
<p class="comment">Figure 6: WebKit shows that Safari has moved the <code>test</code> element into the <code>body</code>.</p>
</li>
<li>
<p>In IE7 the output is &ldquo;Name of bar attribute is language. Value of meta attribute is null&rdquo; &mdash; there are no exceptions reported, and neither result is what was expected. The IE Developer Toolbar&#8217;s DOM view is not quite powerful enough to explain these results &mdash; there are two IE bugs at play here: one is that IE exposes internal generic attributes in the <code>Element.attributes</code> collection, second is that weirdly enough the <code>meta http-equiv</code> attribute simply disappears. See Figure 7 for the output in the IE web developer toolbar.</p>
<p><img src="http://thinkvitamin.com/images/articles/dragonfly/df-dom-demo-app-meta-IE-dev-toolbar.png" alt="the debugging example in the IE web developer toolbar" /></p>
<p class="comment">Figure 7: The IE web developer toolbar does not quite show us the DOM the scripts are working on. It appears to show that IE has preserved the <code>meta http-equiv</code> attribute, yet when we try reading it with the DOM method getAttribute() we get nothing.</p>
</li>
</ul>
<h2>Summary</h2>
<p>Our unlucky developer has a few things to fix to get this example working properly cross-browser, but in this example it&rsquo;s not hard to do so. He&rsquo;ll need to validate the markup, get rid of the custom elements (and avoid these in the future, particularly inside the <code>head</code> as browsers are very picky about what they allow to appear there), and not rely on attribute order when reading attributes. You can see from the examples shown above that valid code is perhaps the most important factor for cross-browser compatibility on the DOM level, and that DOM inspectors help you understand how your scripts can access the document and how the markup is interpreted.</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=1782&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/same-dom-errors-different-browser-interpretations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting &amp; Retrieving Accesskeys with JavaScript and DOM</title>
		<link>http://carsonified.com/blog/dev/setting-retrieving-accesskeys-with-javascript-and-dom/</link>
		<comments>http://carsonified.com/blog/dev/setting-retrieving-accesskeys-with-javascript-and-dom/#comments</comments>
		<pubDate>Thu, 22 Mar 2007 08:26:00 +0000</pubDate>
		<dc:creator>Ian Lloyd</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Accesskeys]]></category>

		<guid isPermaLink="false">http://www.thinkvitamin.com/features/javascript/setting-and-retrieving-accesskeys-with-javascript-and-dom</guid>
		<description><![CDATA[By <strong>Ian Lloyd</strong><br />There are some things in the world of accessibility that appear, on the face of it, to be really wonderful ideas&#8230; until you scratch slightly below the service. What may seem feasible when putting together some guidelines on accessibility might not ultimately translate well to a real-world application. Hands up who can remember the last [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fsetting-retrieving-accesskeys-with-javascript-and-dom%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fsetting-retrieving-accesskeys-with-javascript-and-dom%2F" height="61" width="51" /></a></div><p>There are some things in the world of accessibility that appear, on the face of it, to be really wonderful ideas&#8230; until you scratch slightly below the service. What may seem feasible when putting together some guidelines on accessibility might not ultimately translate well to a real-world application. Hands up who can remember the last time they felt compelled to use a <code>longdesc</code> attribute?  And what about the <code>accesskey</code> attribute? Oh, you <em>have</em> used them you say. OK, let&#8217;s back up a little and find out what went wrong here.</p>
<h3>The Problem With Accesskeys</h3>
<p>The <code>accesskey</code> attribute is a neat little feature that is supposed to enable the user to quickly access a navigation, search, or some other feature of a page quickly. For example, I could use an <code>accesskey</code> of &#8217;s&#8217; for search on a site &#8211; on all sites that I might run &#8211; and have that as the trigger. Depending on the browser or other assistive technology (AT) used, that might involve the user hitting CTRL+s to activate it, or maybe ALT+S, or perhaps some other configuration.</p>
<p>However, those very same commands might be the same as existing commands in the browser or AT. So which command takes precedence? There is another factor to this &#8216;key already assigned&#8217; problem, and that&#8217;s one of localization. While you may think that your browser has a spare key that you could use, in many other languages this won&#8217;t be the case.</p>
<p>Another problem with the <code>accesskey</code> attribute is how do you let the user know about it? As with the <code>longdesc</code> attribute, the availability of the attribute is not really shouted from the rooftops (with the exception of the little-used iCab browser). Unless you make a point of informing the user of <code>accesskey</code>s being used on the site in a separate page, perhaps backed up by judicious use of the <code>title</code> attribute for the relevant links, the user may never know that you made them available.</p>
<p>So it seems that, while accesskeys are a great idea, they are largely hidden and also cause their own set of problems because of the potential overlap with other technology. But wait, maybe there&#8217;s life in the old dog just yet&#8230;</p>
<h3>Let the User Decide</h3>
<p>I have an idea, or rather I <em>had</em> an idea, about the way it might work. I actually used this approach a couple of years ago when I re-built <a href="http://accessify.com/">accessify.com</a>, providing a <a href="http://accessify.com/preferences/accesskeys/">method for the user to set their own accesskeys</a>. They are not forced upon anyone &#8211; it&#8217;s a total opt-in. But in all honesty, it was more of an experiment on a live site than anything else, and it&#8217;s not transferable to other sites unfortunately. The solution was built using PHP, but I always thought that it could be converted to a JavaScript solution. It just took me a couple of years to get around to it (and documenting it!).</p>
<h3>The JavaScript Approach</h3>
<p>In the JavaScript solution, the end result is exactly the same as the version used on Accessify, just the mechanics have changed. Rather than go into all the lines of code and explain everything line-by-line, I&#8217;ll summarise how it works in plain old English.</p>
<ul>
<li>There are a number of links on the example page (the links that we offer up as potential accesskey candidates) By default, they have no <code>accesskey</code> assigned, nor any <code>title</code> attribute:<br />
    <code>&lt;h3&gt;Navigation&lt;/h3&gt;<br />
&lt;ul&gt;<br />
&lt;li&gt;&lt;a href=&quot;/&quot; id=&quot;homelink&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;<br />
&lt;li&gt;&lt;a href=&quot;/search/&quot; id=&quot;searchlink&quot;&gt;Search&lt;/a&gt;&lt;/li&gt;<br />
&#8230;<br />
    </code><code> &lt;/ul&gt;</code></li>
<li>There&#8217;s a warning on the page that says &quot;you need Javascript to set your own accesskeys&quot; &#8211; this is set to display on screen by default<br />
    Finally, there&#8217;s a form that allows you to set the characters you want for the related sections on the page. This is hidden by default (using CSS)<br />
    <code>&lt;p id=&quot;warning&quot;&gt;Cookies are used to save these preferences, but you have either disabled JavaScript, set your browser not to accept cookies, or your browser supports neither. The site will work perfectly well without these preference options.&lt;/p&gt;</p>
<p>    #warning<br />
  {<br />
color:red;<br />
}</p>
<p>function hideWarning()<br />
  {<br />
  <strong>var elwarn = document.getElementById(&#8217;warning&#8217;);<br />
  elwarn.style.display=&quot;none&quot;;</strong><br />
var elsetter = document.getElementById(&#8217;setter&#8217;);<br />
elsetter.style.display=&quot;block&quot;;<br />
}</code></li>
</ul>
<p>If the user gets to the page with JavaScript disabled (or with the scripts not properly downloaded &#8211; perhaps blocked by a firewall), they will essentially get the default page that says &quot;You can&#8217;t do this, you need JavaScript to set this stuff&quot; and no facility to set it is displayed.</p>
<p>If JavaScript is available, though, it&#8217;s a slightly different scenario:</p>
<ul>
<li>The warning message that&#8217;s set to display by default gets suppressed (after page load, by having the CSS <code>display</code> property set to <code>none</code>)</li>
<li> The form that accepts the user&#8217;s desired <code>accesskey</code> assignments is made visible (again, using JavaScript to change the CSS <code>display</code> property)</li>
</ul>
<p>Now that we know that the user has JavaScript enabled and was able to get all the source files correctly, they can then go ahead and save their accesskeys.</p>
<h3>Saving the Accesskey Choices</h3>
<p>The process of saving the choices made by the user are fairly standard JavaScript/cookie methods &#8211; one long string is saved that has a number of property:value pairings (one for each link or button that can potentially be assigned an acccesskey). For example:</p>
<p><code>&lt;form action=&quot;set-access-keys.htm&quot; method=&quot;post&quot; name=&quot;frmAccessKeys&quot;&gt;<br />
&lt;fieldset&gt;</p>
<p>&lt;legend&gt;Set Accesskeys for &#8230; &lt;/legend&gt;</code></p>
<p><code>&lt;div&gt;<br />
&lt;label for=&quot;txthomelink&quot;&gt;Home link&lt;/label&gt;<br />
&lt;input value=&quot;&quot; name=&quot;txthomelink&quot; id=&quot;txthomelink&quot; type=&quot;text&quot; size=&quot;2&quot; maxlength=&quot;1&quot; /&gt;<br />
&lt;/div&gt;</code></p>
<p><code>&lt;div&gt;<br />
&lt;label for=&quot;txtsearchlink&quot;&gt;Search Box&lt;/label&gt;<br />
&lt;input value=&quot;&quot; name=&quot;txtsearchlink&quot; id=&quot;txtsearchlink&quot; type=&quot;text&quot; size=&quot;2&quot; maxlength=&quot;1&quot; /&gt;<br />
&lt;/div&gt;</code></p>
<p><code>...</code></p>
<p><code>&lt;/fieldset&gt;<br />
&lt;/form&gt;</code></p>
<p><code>strKeyVals += &quot;homelink=&quot; + document.forms['frmAccessKeys'].txthomelink.value + &quot;@@&quot;;<br />
  strKeyVals += &quot;searchlink=&quot; + document.forms[&#8217;frmAccessKeys&#8217;].txtsearchlink.value + &quot;@@&quot;;</code></p>
<p>The <code>@@</code> is simply there to make it easier to identify where to split the string when retrieving the data from the saved cookie later.</p>
<p>We also provide an option for the user to get a hint of the <code>accesskey</code> for each link or button with the use of a simple checkbox:</p>
<p><code>&lt;div&gt;<br />
&lt;input type=&quot;checkbox&quot; name=&quot;chkshowhint&quot; id=&quot;chkshowhint&quot; /&gt;<br />
&lt;label for=&quot;chkshowhint&quot; class=&quot;check&quot;&gt;Show accesskeys in links and buttons (displayed after link in brackets)&lt;/label&gt;<br />
&lt;/div&gt;</code></p>
<p><code>strKeyVals += &quot;showhint=&quot; + document.forms['frmAccessKeys'].chkshowhint.checked + &quot;@@&quot;;</code></p>
<p>The process for capturing the information is initiated by an <code>onclick</code> event attached to the submit button, which passes it through to an <code>addevent</code> function:</p>
<p><code>addEvent(document.getElementById('cmdSubmit'), 'click', accessKeySetter, false);</code></p>
<p>(The function accessKeySetter is where the JavaScript code snippets above appear)</p>
<h3>Remembering the Choices and Updating the Display on Page</h3>
<p>Assuming the user has entered some values and also chosen to have the accesskeys showing in the links or buttons, once the page has reloaded following the submit, this is where the DOM really takes over.</p>
<p>Remember, we start with a page that has a number of links that have neither default <code>accesskey</code> or <code>title</code> attributes present, then we use JavaScript to present the option to manipulate/store <code>accesskey</code>s (if JavaScript is not available for whatever reason, the default page display is to warn them that they can&#8217;t do this and need to get their JS in order, or words to that effect). So, already, we&#8217;re using JavaScript in a nice <a href="http://en.wikipedia.org/wiki/Progressive_enhancement">progressive enhancing</a> kinda way. The final stage is to use JavaScript and the DOM to update the page display depending on what&#8217;s found in the cookie. The steps to do this are as follows:</p>
<ol>
<li>Firstly, look for the presence of the <code>accesskey</code> cookie</li>
<li>Assuming it&#8217;s found, take the content of that string and split it up into the individual links/buttons that it repesents (separated by the <code>@@</code> characters that were shown earlier<br />
    <code>//get the cookie<br />
    var strAccessKeys = readCookie(&quot;accesskeys&quot;);<br />
    //split up the values<br />
  var arrAccesskeys = strAccessKeys.split(&quot;@@&quot;);</code></li>
<li>Then, each value found is split between the <code>id</code> of the link or button it represents and the value stored against each (the <code>accesskey</code> the user wants to assign)<br />
    <code>for (i=0;i&lt;(arrAccesskeys.length-2);i++)<br />
    {<br />
    var thisAccessKey 	= arrAccesskeys[i].split(&quot;=&quot;);<br />
    var accessKayEl 	= thisAccessKey[0];<br />
  var accessKayAttrib	= thisAccessKey[1];<br />
  &#8230;</code></li>
<li>Then it&#8217;s a case of running through the array of <code>id</code>s in the cookie that have values assigned and matching them up to the <code>id</code>s of elements on the page and then:
<ol>
<li>adding the accesskey value to the element<br />
        <code> if (accessKayAttrib.length&gt;0)<br />
        {<br />
        //set the attribute<br />
        document.getElementById(accessKayEl).setAttribute(&#8217;accesskey&#8217;, accessKayAttrib);</code></li>
<li>and updating the content of link or value of the button text to display the accesskey (if the user has requested this), and adding a title attribute too:<br />
        <code>    if (document.getElementById(accessKayEl).tagName==&quot;A&quot;)<br />
        {<br />
        var strLinkPhrase = document.getElementById(accessKayEl).childNodes[0].nodeValue;<br />
        }<br />
        if ((document.getElementById(accessKayEl).tagName==&quot;INPUT&quot;) &amp;&amp; ((document.getElementById(accessKayEl).type==&quot;submit&quot;)||<br />(document.getElementById(accessKayEl).type==&quot;button&quot;)))<br />
        {<br />
        var strLinkPhrase = document.getElementById(accessKayEl).value;<br />
        }<br />
        <strong>document.getElementById(accessKayEl).setAttribute(&#8217;title&#8217;, strLinkPhrase + &#8216;, access key = &#8216; + accessKayAttrib);<br />
        </strong>//display the accesskey hint, if that&#8217;s been chosen<br />
        if (blnShowHints)<br />
        {<br />
        <strong>strLinkPhrase = strLinkPhrase + &quot; [&quot; + accessKayAttrib + &quot;]&quot;;<br />
        </strong>if (document.getElementById(accessKayEl).tagName==&quot;A&quot;)<br />
        {<br />
        document.getElementById(accessKayEl).childNodes[0].nodeValue = strLinkPhrase;<br />
        }<br />
        if (document.getElementById(accessKayEl).tagName==&quot;INPUT&quot;)<br />
        {<br />
        document.getElementById(accessKayEl).value = strLinkPhrase;<br />
        }</code></li>
</ol>
</li>
<li>One final step, while traversing through the page, is to add the value chosen in to the form fields too, so they&#8217;re remembered, likewise the state of the checkbox.</li>
</ol>
<p>The <a href="http://www.thinkvitamin.com/misc/accesskeys/set-access-keys.htm">final result is a completely unobtrusive method for setting and remembering accesskey attributes</a> which doesn&#8217;t enforce itself on the user &#8211; it&#8217;s completely opt-in.</p>
<p>[<a href="http://www.thinkvitamin.com/misc/accesskeys/final.zip">download the zipped version with all files required here.</a>] </p>
<h3>Possible Improvements</h3>
<p>The biggest improvement that could happen with this script is to have it centralized somewhere, or some variant thereof, so that it could be re-used in some way. My thinking was that if this mechanism were possible to re-use across sites, then a user could potentially save some accesskey choices that would be usable for a number of different sites, but then there&#8217;s one fatal flaw in this idea &#8211; a cookie can only be read back by the same domain, thus if I were to set my choice for site whateverxyz.com, when I try to do the same for abcwhatever.com, it won&#8217;t be able to read back the same data. So I&#8217;m definitely open to suggestions as to how that might be made possible at some time in the future.</p>
<h3>Outside Reading </h3>
<p>This isn&#8217;t the first time someone has come up with a method for dealing with this, so here are a few other takes on how to solve the issue:</p>
<ul>
<li><a href="http://juicystudio.com/article/user-defined-accesskeys.php">Gez Lemon&#8217;s PHP-based accesskey setter</a></li>
<li><a href="http://golem.ph.utexas.edu/~distler/blog/archives/000723.html">Jacques Distler&#8217;s JavaScript approach  </a></li>
</ul>
<p>And if you want to to learn more about the background to the problem, here are a couple of recommended reads:</p>
<ul>
<li>Dave Shea: <a href="http://www.mezzoblue.com/archives/2005/01/05/keyboards_an/">Keyboards and Chaos</a>  </li>
<li>Derek Featherstone: <a href="http://www.boxofchocolates.ca/archives/2003/12/06/accesskey-conflicts">Accesskey Conflicts</a> </li>
</ul>
<img src="http://carsonified.com/?ak_action=api_record_view&id=1739&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/setting-retrieving-accesskeys-with-javascript-and-dom/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>15 Things You Can Do with Yahoo! UI</title>
		<link>http://carsonified.com/blog/dev/15-things-you-can-do-with-yahoo-ui/</link>
		<comments>http://carsonified.com/blog/dev/15-things-you-can-do-with-yahoo-ui/#comments</comments>
		<pubDate>Sun, 02 Jul 2006 08:00:25 +0000</pubDate>
		<dc:creator>Dustin Diaz</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.thinkvitamin.com/features/javascript/15-things-you-can-do-with-yahoo-ui</guid>
		<description><![CDATA[By <strong>Dustin Diaz</strong><br />I will admit straight up front &#8211; I don&#8217;t like writing long articles. There, I said it. I passed College English convincing my professors that I should be rewarded more for my creativity rather than the length of my prose. I&#8217;m the kind of guy that spent more time writing short stories than huge complicated [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2F15-things-you-can-do-with-yahoo-ui%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2F15-things-you-can-do-with-yahoo-ui%2F" height="61" width="51" /></a></div><p>I will admit straight up front &#8211; I don&#8217;t like writing long articles. There, I said it. I passed College English convincing my professors that I should be rewarded more for my creativity rather than the length of my prose. I&#8217;m the kind of guy that spent more time writing short stories than huge complicated essays. Eventually I went on to write for the school Newspaper, a.k.a. <a href="http://www.statehornet.com" title="CSU Sacramento's Student Newspaper">The State Hornet</a> which gave me the freedom to keep my stories to a minimum of 500 words, or just a couple of paragraphs.</p>
<p>Today that legacy still stands and has transferred into my love for making widgets. No, not <a href="http://widgets.yahoo.com/" title="Previously known as Konfabulator">those widgets</a>. I&#8217;m talking about those little goofy things you do on a Sunday afternoon from when you had that idea on Saturday night which left you frustrated on Friday after work. Yes, you&#8217;re not the only one with crazy ideas.</p>
<p>I&#8217;m talking about sliders, yoyos, tooltips, shakers, better looking code, faster queries, and random jubilees of DOM hoopla. It&#8217;s those small things that some of us live to create and find it rewarding even if it&#8217;s one line of code. And although these little works of &#8216;code art&#8217; don&#8217;t always work on all browsers while having labels of &#8216;experimental&#8217; written all over them, don&#8217;t feel ashamed of them. They come from you and you should embrace your work. You are, a Web Professional.</p>
<h3>Segue</h3>
<p>In this article I&#8217;m going to share some of my <q>short stories</q>, <q>poems</q>, and random sonnets of affectionate escapades I&#8217;ve had with JavaScript during the last few months, which I&#8217;ve built using the <a href="http://developer.yahoo.com/yui" title="Yahoo. Woot!">Yahoo UI</a> utilities. Some are rather embarrassing, others useful, and yet others I feel are just downright sexy. If you see something you like, feel free to take it, tweak it, and make it your own. This is what some poetry afficionados of secret societies would call a <q>poetry slam</q>. So for want of a better phrase, this can be a &lt;code slam&gt;.</p>
<h3>Why YUI?</h3>
<p>The <abbr title="Yahoo User Interface">YUI</abbr> utilities give me the expressive freedom to do what I want. And although comparing libraries is generally silly, the best illustration I can give is the <a href="http://script.aculo.us">Script.aculo.us</a> Effects library vs the <a href="http://developer.yahoo.com/yui/animation">YUI Animation utility</a>. Script.aculo.us offers you some pretty sweet looking effects like Fade, SlideUp, BlindDown, Shake, etc.. You can even add Parallel effects (way to go Thomas). On the flip side, the animation util doesn&#8217;t aim to give you these canned effects to package up with your web app, but rather it lets you make up your own effects by giving you the finely crafted tools (like a utility knife) to make what you want. </p>
<p>Another reason I like YUI is that it isn&#8217;t out to change the language itself, but rather it solves many of the cross-browser incompatibilities that we run into on a daily basis. Beyond that, it does quite a few other sexy things that I think you might like.</p>
<h3>Code</h3>
<p>Below is a compilation of fifteen things that I have either developed over the last few months, or have been inspired by a friend (who will receive full credit on the original idea). <strong>Enjoy!</strong></p>
<h3>DOM + The getElementBy&#8217;s</h3>
<p>These days, when you&#8217;re working with the DOM, it&#8217;s all about getting the elements you want, with conditions applied. Thankfully the Dom util doesn&#8217;t go all out and try to do all the guesswork for you resulting in a bulky library with large sets of unwanted code. Instead it gives you a handy method for you to work with called getElementsBy.</p>
<h3>YAHOO.util.Dom.getElementsByClassName</h3>
<p>Let&#8217;s kick off our slam with the classic getElementsByClassName (which is actually in the utility by default). I like to think of it as our token example by the YUI folks showing off how getElementsBy can work natively within your functions. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-01.html">See Demo</a></p>
<h3>getElementsByAttribute</h3>
<p>This method is not in the Dom util by default, but demonstrates exactly how we can add it in if we wanted. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-02.html">See Demo</a></p>
<h3>getElementsByExternal &amp; getElementsByInternal</h3>
<p>This function allows you to get outbound or inbound links returned to you as an HTMLElement collection. At that point it&#8217;s up to you what you want to do with your array of elements (eg. bind event listeners or run a method against them). Currently this is untested on IP address URIs, but I presume that won&#8217;t be an issue for most situations. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-03.html">See Demo</a></p>
<h3>Random Effects of Love</h3>
<p>Because everyone enjoys California cheese.</p>
<h3>Pagination Slide Pattern</h3>
<p>Paginating through large data sets and keeping someone&#8217;s attention can be a tedious task. Sliding results within a container is one way to keep a person entertained. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-04.html">See Demo</a></p>
<h3>BlindUp &amp; BlindDown (Yoyo)</h3>
<p>These are classic effects that almost any animation lover would want in their toolkit. For the sake of making them a macro, here they are. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-05.html">See Demo</a></p>
<h3>BlindOut</h3>
<p>A demonstration of animating a box from any given corner. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-06.html">See Demo</a></p>
<h3>Faux Mutation Events with CustomEvent</h3>
<p>Most folk don&#8217;t know what mutation events are, mainly because they don&#8217;t work in IE6. These are events just like regular DOM events like &#8216;click&#8217;,&#8217;mouseover&#8217;, or &#8216;mouseout&#8217; that you can listen for. Just to name a few there are &#8216;DOMNodeInserted&#8217;, &#8216;DOMNodeRemoved&#8217;, and &#8216;DOMNodeInsertedIntoDocument&#8217;. For a better reference you can see <a href="http://en.wikipedia.org/wiki/DOM_Events">Wikipedia&#8217;s entry on DOM events</a> and search for the Mutation events within the event table. Anyway, here&#8217;s how you can simulate some of those events using the CustomEvent class.</p>
<h3>DOMNodeInserted</h3>
<p>Create some elements, listen for the event, then make them draggable. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-07.html">See Demo</a></p>
<h3>DOMNodeRemoved</h3>
<p>Create some elements, then remove them to update an information box. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-08.html">See Demo</a></p>
<h3>More with CustomEvents</h3>
<p>There really is an endless amount of Custom Events that you can create. So we&#8217;ll keep this to a minimum. Here are three places that the CustomEvent can come in useful:</p>
<h3>Extending the Drag and Drop</h3>
<p>Currently, the Drag and Drop utility is packaged with quite a few custom events you can override such as startDrag, onDrag, or endDrag. However the problem is that you can&#8217;t subscribe to any of these, only override. Here is one trick you can use to make them <q>subscribable</q>. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-09.html">See Demo</a></p>
<h3>onMenuOpen &amp; onMenuCollapse</h3>
<p>This is a combination of animation and custom events where we show menu items sliding into view and firing off subscribable events. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-10.html">See Demo</a></p>
<h3>General Recipes</h3>
<p>None of these have any rhyme or reason. But I tend to think that in some place or another, they can solve a problem.</p>
<h3>Sweet Titles (YUI Style)</h3>
<p>Here we have an OO version of <a href="http://www.dustindiaz.com/sweet-titles/">Sweet Titles</a> that allows us to declare multiple instances of tooltips on separate elements with some optional configuration parameters you can pass into the constructor object to get that exact look and feel you want out of a tooltip. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-11.html">See Demo</a></p>
<h3>Faux Lightbox Effect</h3>
<p>For the sake of doing something that&#8217;s already been done, here&#8217;s a faux light box effect that can be obtained using some core tools. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-12.html">See Demo</a></p>
<h3>Photo Batching</h3>
<p>YAHOO.util.Dom.batch alone may convince you of how cool the DOM Collection utility can be. This shows you how you can batch an HTML Element collection to a method. (Thanks Matt Sweeny) <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-13.html">See Demo</a></p>
<h3>Unobtrusive new windows links</h3>
<p>For some reason or another, this always seems to create some noise regardless of its controversial nature. Here is a very simple way to do it with Event, DOM, and some of the tools we&#8217;ve defined in this very article. <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-14.html">See Demo</a></p>
<h3>Layout Switching with Grids</h3>
<p>This is a combination of using the CSS Grids toolkit and swapping out the templates using JavaScript animation <a href="http://www.thinkvitamin.com/misc/yui-demos/demo-15.html">See Demo</a></p>
<h3>That&#8217;s All Folks</h3>
<p>At least for this article&#8217;s sake. There are plenty of other things you can making using the Yahoo! UI utilities and this has only scratched the surface. I hope it was as fun for you as it was for me.</p>
<p class="diggit"><img src="http://www.digg.com/img/digg-guy-small.gif" alt="digg.com logo" /> Like this article? <a href="http://digg.com/programming/15_things_with_Yahoo_UI">Digg it</a>!</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=1696&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/15-things-you-can-do-with-yahoo-ui/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
	</channel>
</rss>
