Fragment Highlight
06 June 2004
Deprecated
In light of improvements to browsers, I consider this code redundant and deprecated. I no longer maintain it.
Introduction
Fragment Highlight aids a user in locating the section of a document they linked to, by highlighting the relevant heading. This functionality is equivalent to the proposed :target selector for CSS 3 but works in earlier browsers and conforms to current (i.e. not proposed) standards.
It is written in JavaScript, with a strong focus on the separation of content, presentation, and logic. It is designed to gracefully degrade so that it works in supporting browsers and causes no problems in unsupporting browsers.
The script can be seen in action on this site, try the table of contents for this page (above) if you have a supporting browser.
Browser Support
This data assumes browsers with JavaScript and CSS enabled. It is assumed that a later version of the same browser will support the script. If a browser is not listed, it has not been tested (reports of support in other browsers would be welcome).
Browser | Version | Support |
---|---|---|
Netscape | 4 | No |
Mozilla | 1.3 | Yes |
Konqueror | 3.1.1 | Yes |
Opera | 7.1 | Yes |
Internet Explorer for Windows | 6 | Yes |
Download
You can download the script from Github.
Install
The script is designed to work with minimal changes to the HTML code. The HTML must be suitably semantic, a style sheet must be written, then the script can be dumped in.
HTML
Links
Links to specific parts of an HTML document take the form:
<a href="#fragment">text</a>
.
This script functions only on:
- Links from external documents
- Links in which the first character of the href is "#"
The script will not function on links of the form:
<a href="currentPage.html#fragment">text</a>
.
Targets
In modern HTML, document fragments are identified with an id
attribute on arbitrary elements. For example: <h3
id="fragment">text</h3>
. The script will recognise
any target taking this form.
Previously, links including fragment identifiers took the form:
<a name="fragment">text</a>
.
This form has been deprecated and the script will not recognise them. It is possible that the script will recognise fragment identifiers of this form in future, but it seems unlikely.
CSS
The script works by changing the class of targeted elements, a style must be defined to describe how targeted elements (with the class "fragment") should look.
I have the following code in my style sheet:
.fragment {
background-color: yellow;
color: black;
}
JS
The JavaScript can be included in an existing script, or included separately.
<script type="text/javascript" src="hi.js"></script>
If you have existing scripts activated in the onload event, it is very important that you merge the onload event handler from the highlight script with your existing script.
You may wish to edit other parts of the script, notably the definition of "var fragExclude".
How it works
Declarations
As the document loads, the script defines a couple of variables.
fragHLed stores the value of the currently targeted fragment (which is blank, at least until the document has finished loading and the onload event is triggered.
You should edit fragExclude to be a list of ids that you do not
wish to be highlighted. In this case <foo
id="header">
is excluded as it is used by the Skip navigation link.
var fragHLed = '';
var fragExclude = ('header');
Array Search
This is used to search the array to make sure that the fragment being visited isn't on the "do not highlight" list.
Array.prototype.search = function(myVariable) {
for(x in this) if (x == myVariable) return true; return false;
}
fragHL()
This unhighlights any existing elements that have been highlighted, then highlights the specified one.
function fragHL(frag) {
if (fragHLed.length > 0 && document.getElementById(fragHLed)) {
KillClass(document.getElementById(fragHLed),'fragment');
}
if (frag.length > 0 && document.getElementById(frag)) {
fragHLed = frag;
AddClass (document.getElementById(frag),'fragment');
}
}
fragHLload()
This is called by the onload event handler, it extracts the value after the "#" in the requested URL and calls fragHL
function fragHLload() {
fragHL(location.hash.substring(1));
}
fragHLlink()
This scans the document for links that have href attributes with values starting with a "#". It then adds onclick events to each to call fragHL().
function fragHLlink() {
if (document.getElementsByTagName) {
var an = document.getElementsByTagName('a');
for (i=0; i<an.length; i++) {
if (an.item(i).getAttribute('href').indexOf('#') >= 0) {
var fragment = an.item(i).getAttribute('href').substring(
an.item(i).getAttribute('href').indexOf('#') + 1
);
if (fragExclude.search(fragment)) {
var evn = "fragHL('" + fragment + "')";
var fun = new Function('e',evn);
an.item(i).onclick = fun;
}
}
}
}
}
Onload
This calls the relevant functions needed at load time, should there be an existing onload handler, this will overwrite it - so the two should be merged.
window.onload = function(){
fragHLload();
fragHLlink();
};