<ABBR> in Internet Explorer
It is a pretty well known fact that Win/IE fails to support this simple, yet semantically import, HTML tag. But don't let that stop you from using it!
document.documentElement.setAttribute("xmlns:acc", "http://www.w3.org/1999/xhtml");
document.body.innerHTML = document.body.innerHTML.replace(/<abbr/gi, "<acc:abbr").replace(/<\/abbr/gi, "</acc:abbr");
See those two lines of code? May not seem like much, but there is a lot of stuff going on. Here's an explanation, line-by-line:
document.documentElement.setAttribute("xmlns:acc", "http://www.w3.org/1999/xhtml");
Alright, so why am I dynamically setting a namespace? When Internet Explorer encounters an unknown tag, e.g. ABBR, it does a few things. Let's pretend this is our markup: <abbr title="Boulevard">Blvd</abbr>.
When it creates the representation in the DOM, a lot of counter-intuitive things happen. The expected DOM representation should be something like an HTMLUnknownElement with a single child of TextNode. However, what IE sees is "HTMLUnknownElement TextNode HTMLUnknownElement" (all siblings), where the first node's name is "ABBR", the second's is "#text", and the third's is "/ABBR"!!! With this representation, you cannot directly style or apply attributes such as title to the contained text.
There is a solution though. In Win/IE5, Microsoft implemented XML namespaces, but in HTML interestingly enough. See http://msdn.microsoft.com/workshop/author/dhtml/overview/customtags.asp. Basically, I set an acc namespace (pointed to the XHTML namespace to keep the semantics identical) in order to make IE recognize attributes such as title and class on the tag.
document.body.innerHTML = document.body.innerHTML.replace(/<abbr/gi, "<acc:abbr").replace(/<\/abbr/gi, "</acc:abbr");
This line takes a snapshot of the BODY's HTML content, and replaces all ABBR with acc:abbr, which allow title attributes and such. Simple enough.
You can see it in action at the following page: ie-abbr.html
Delivering the Code
When I was first writing this code, I had it like this:
<script language="Jscript" event="onload" for="window">
document.documentElement.setAttribute("xmlns:acc", "http://www.w3.org/1999/xhtml");
document.body.innerHTML = document.body.innerHTML.replace(/<abbr/gi, "<acc:abbr").replace(/<\/abbr/gi, "</acc:abbr");
</script>
This automatically hid it from non-IE browsers, and attached it to the onload event for me. However, none of those attributes are valid XHTML. If you are including the script underneath an IE-only conditional comment (like I use on this website, view the page source for an example), then I'd recommend using this. Otherwise, use the other method described next.
<script type="text/javascript">
if (typeof window.attachEvent != "undefined" && typeof window.opera == "undefined") { // Internet Explorer for Windows
window.attachEvent("onload", function() {
document.documentElement.setAttribute("xmlns:acc", "http://www.w3.org/1999/xhtml");
document.body.innerHTML = document.body.innerHTML.replace(/<abbr/gi, "<acc:abbr").replace(/<\/abbr/gi, "</acc:abbr");
});
}
</script>
Since I'm using attachEvent() to not interfere with the window.onload property, I decided I might as well check for IE with it as well. Really, it isn't quite logically sound to use window.attachEvent if document.all is defined (the typical object detection method). Also, notice the check for Opera. This little gotcha was discovered by Chris Aitken. Opera correctly supports ABBR, and also supports attachEvent(), but does not support custom HTML elements like this, entirely removing the subtree from the document (instead of using an HTMLUnknownElement interface). The check simply keeps Opera from rewriting the page. Also, this script can be saved in an external .js file and cached, to be easily included on several pages.
Also, why not use a favelet? If you are using Win/IE (I'm sorry), you can make ABBR's work for you by running this favelet:
javascript:document.documentElement.setAttribute("xmlns:acc", "http://www.w3.org/1999/xhtml");document.body.innerHTML = document.body.innerHTML.replace(/<abbr/gi, "<acc:abbr").replace(/<\/abbr/gi, "</acc:abbr");void(null);
Usage
I'm not going to even bother licensing this script. Use freely. Commercial. Non-commercial. However you want, it's all good. I won't even force you to give me any credit (but you certainly shouldn't take credit, that's plagiarism), but a little comment in your source code would be much appreciated. ABBR hack by Jason Davis (www.jasonkarldavis.com/scripts/abbrhack)
would be perfect.
Alternatives
I found this on google while writing up this page for distributing the script: http://www.sovavsiti.cz/css/abbr.html. The disadvantages of this approach is that the source, even if dynamic, is littered with excess SPAN elements. The compatibility-level should still be about the same (that might work in IE4 and mine won't), however their RegExp search and replace method doesn't allow for nested markup (e.g. EM elements inside the ABBR) and they overwrite the window.onload handler, which may interfere with other scripts on the page using it. My script actually keeps the exact same tag with the exact same semantics, and leaves it in an equivalent namespace, but just gives it a different qualified name.