Associated with nearly every HTML element is a core group of events [ed.—which trigger event handlers, blah, blah, blah... Is this going to be another geek post?], and you might just find you have a use for them.
Jeffrey’s ongoing style switching problems, prompted me to throw my two cents in regarding an option (not as a fix or workaround) I thought he might not have considered. Initially, his style switching widget was using images with links like <a href="#">, and calling the JavaScript function, which set the style, from the onclick event of the link. Pretty standard stuff really. Using the hash mark (#), or the JavaScript void operator (javascript:void(0)) for null links is in just about every DHTML book I own. [ed. note—As a historical bit of trivia for those playing along at home, early MovableType adopters can thank us or slap us, but it was at our suggestion that MT’s comment links switched from using # to javascript:void(0) in order to get around IE’s page jumping problem.] Lately though, both are becoming sort of bad form.
After reading a few articles such as Aaron’s How to Create Pop-Up Windows, where he said “forget you ever knew that the javascript pseudo-protocol ever existed”
, I removed it from my thinking and my coding. This brought me to the point of rethinking how I add JavaScript functionality. I started thinking that since nearly every element has the same set of core events, things that I used to turn into null links just to trigger event handlers, no longer needed to be, or should be a link. And actually, there is no reason to use null links at all.
Accessibility and usability issues have shown us the way to improving how we use JavaScript with links, but there are those scenarios where it’s a judgement call as to whether or not a link is necessary. In the case of Jeffrey’s style switching widget, he now links to a page explaining how the switcher works, which enhances the accessibility/usability of his site, but the level of functionality en route to accessibility/usability is a judgement call that he made. In point of fact, Jeffrey was only using the style switcher in the manner it was first introduced by Paul Sowden in Alternative Style - Working With Alternate Style Sheets, so he has only improved the usability of it on his site. However, Todd Dominey’s style switcher uses images and null links, so I will use his site as an example of what I explained to Jeffrey.
In my email to him, I proposed triggering the onClick event handler of the IMG element instead of wrapping the image in a link for the sole purpose of using the anchor element’s onClick event. Since what we’re really after here is the functionality, and not providing a link to a resource, there’s no reason to use the A element at all. Taking an example from Todd’s site, his code looks like the following:
<a href="#" onclick="setActiveSS('Largest Text');return false;"><img src="/images/widget_typeLg.gif" alt="Largest Text Size" width="24" height="24" />< /a>
The use of return false; is there to tell the browsers not to follow the link. Reformatted without the link it looks like this:
<img src="/images/widget_typeLg.gif" onclick="setActiveSS('Largest Text');" alt="Largest Text Size" width="24" height="24" />
Same functionality, and in my opinion a more appropriate use of the markup.
Yes, but how will people know it’s a link? Well, first, it’s not a link, it’s a clickable element. Don’t confuse links with clickability. Second, a touch of CSS and it will be visually indistiguishable from a link. So lets set up a class for clickable images.
img.iClick {
cursor: pointer;
cursor: hand;
}
Once this class has been added, when hovering over the image, the browsers will display their default link cursor informing the user that the element is clickable. Why two cursor definitions? Let Eric Meyer tell it. Adding cursor: hand; is really not valid CSS, but I see it as a minor infraction that I can live with in favour of usability.
Ok, but what about accessibiity issues? Well, I was thinking about this, and I decided that you could use longdesc to specify the URI of a document similar to Jeffrey’s, which explains the functionality that the image is meant to trigger. So in an effort to bring together functionality, usability, and accessibility, we now get the following:
<img class="iClick" src="/images/widget_typeLg.gif" onclick="setActiveSS('Largest Text');" onkeypress="setActiveSS('Largest Text');" width="24" height="24" alt="Largest text icon" longdesc="http://www.whatdoiknow.org/switch/" title="Click for the Largest Text Size" />
Want a working example? You’re soaking in it. Every time you’ve ever accessed my navigation menu by clicking on the little menu image, you’ve been using a clickable image and not a link. It’s been this way since I implemented the hidden nav thing.
You might be wondering if my contention is that this is only for images. Not at all. The same idea can be applied to any element. As a further example, I reformatted the search link in the navigation. Prior to today it was formatted as a link, and I used the onclick event of the link to make the draggable search box visible/invisible. To cover accessibility/usability issues, the URI pointed to a JavaScript Required page. What I’ve done instead, since the nav is marked up as an unordered list, is remove the link and use the onClick event of the LI element that contains the text. I’ve applied a class with cursor styles as well as a :hover style, and for nearly everyone it should look and function exactly the same as it always has.
No I’m not trying to say you should be adding all your JavaScript to the event handlers in the markup, just that there are situations where it might be appropriate. It’s a choice. There are interesting choices to be made when designing. For instance, you could use it to add something interesting to an instance of the DFN element in a similar fashion to Alison’s footnote thing.
Example: elephants
The code for which looks like the following (this example uses inline styles):
<dfn style="color:red; border-bottom:1px dotted black; cursor: pointer; cursor: hand;" title="Nevermind the pink ones." onclick="alert(this.getAttribute('title'));">elephants</dfn>
Or you could extend the functionality of the BLOCKQUOTE element, using the cite attribute, to make the entire quote clickable, allowing users to link to the resource you cited, as in the following example, which also uses onMouseOver and onMouseOut:
“My system, as well as Stuart’s, employ unobtrusive Javascript that does not put any Javascript in the actual markup. Instead, the Javascript is linked in the source, and all of the work is done using DOM selectors.”
The code for the BLOCKQUOTE example looks like the following (this example uses inline styles):
<blockquote style="color:#999; background-color:#ddd; border:1px solid #999; cursor: pointer; cursor: hand;" cite="http://www.readinged.com/blog/50/" title="Reading Ed: Unobtrusive Changes and Unobtrusive Javascript" onclick="window.location=this.getAttribute('cite');" onmouseover="this.style.color='#000'; window.status=this.getAttribute('title')+' - '+this.getAttribute('cite');" onmouseout="this.style.color='#999'; window.status='';"><p>“My system, as well as Stuart’s, employ unobtrusive Javascript that does not put any Javascript in the actual markup. Instead, the Javascript is linked in the source, and all of the work is done using DOM selectors.”</p></blockquote>
Yes I know there are other, better ways to do this. Like the unobtrusive Javascript that Ed is talking about. And actually if we took Ed’s example and extended it to do what I just did inline, it might look like this:
window.defaultStatus = "Initial Status"; // Change me
window.onload = function()
{
var theQuote = document.getElementsByTagName("blockquote");
for (var i = 0; i < theQuote.length; i++)
{
thisTitle = theQuote[i].getAttribute("title");
if (!thisTitle) continue;
theQuote[i].onmouseover = function()
{
window.status = this.getAttribute("title") +
" (" + this.getAttribute("cite") + ")";
return true;
};
theQuote[i].onmouseout = function()
{
window.status = window.defaultStatus;
return true;
};
theQuote[i].onclick = function()
{
window.location = this.getAttribute("cite");
return true;
};
}
};
And instead of adding the JavaScript to each BLOCKQUOTE element individually, this would recursively run through all BLOCKQUOTE elements in a document, making them clickable, using the value of the cite attribute as the URI to link to, as well as displaying it and the title in the status bar. Again, I’m not saying any one method is better than the other [ed.—although we like the idea of unobtrusive Javascript very much!], just that you have other interesting options you could take advantage of. It’s that million dollar markup thinking. The richer your markup is, the more functionality you can get out of it.
3 responses so far ↓
1 J i m // Feb 15, 2003 at 9:38 am
Like I’ve told you before, I’m taking the classes and showing up on time. And, while it looks like I’m taking notes, I’m actually doodling in the margins waiting for the lunch bell to ring.
2 Andrew // Feb 24, 2003 at 12:33 pm
The only thing I really have against that option (concerning the blockquote) is that it won’t allow me to use tabbed browsing since it doesn’t see it as a link and there isn’t a "copy link location" or the ability to use ctrl+shift+left click (for Mozilla).
3 michael // Feb 24, 2003 at 11:59 pm
Andrew, I agree with you to a point. If the example were detracting from the content’s usefulness in some way then yes, but since BLOCKQUOTEs don’t inherently have any linking ability (at least not until XHTML2 is released), I see the example as enhancing its usefulness. I could of course ADD a link to the page that is useful for tabbed browsing and copying link locations, but understanding the URIs in CITE attributes, and such, is also a feature that the browsers could add, no?
Lastly, all the examples were used more as examples of utilizing each elements event attributes, than actual examples of scripting enhancements that I felt people should implement.
You must log in to post a comment.