This is a quick post to present a JavaScript that provides CSS3 :target pseudo selector like functionality for browsers that do not provide native :target support.
function() {
var cssClass = 'target';
// Initialise targeted fragments if any.
var target = document.getElementById(window.location.hash.slice(1));
if (target) {
target.className += ' ' + cssClass;
}
// Click event handler function generator. This is passed a "frag" argument
// that is a reference to the target element.
var reCSS = new RegExp("\\b" + cssClass + "\\b");
function newTargetClickHandler(frag) {
return function() {
if (target) {
target.className = target.className.replace(reCSS, '');
}
target = frag;
target.className += ' ' + cssClass;
}
}
// Run thru <a> elements and add an onclick handler to those that reference
// document fragments within the current page.
var reURI = new RegExp('^' + window.location.href.match(/^[^#]+/)[0] + '#([^#]+)$');
var elems = document.getElementsByTagName('a');
for (var i=0; i<elems.length; i++) {
if (elems[i].href && elems[i].href.match(reURI)) {
elems[i].onclick = newTargetClickHandler(document.getElementById(RegExp.$1));
}
}
};
When the user clicks on a link that points to a fragment within the current page, this code will add a CSS class of “target” to the targeted element, and will remove the same “target” class from any previously targeted element.
Originally I was using the CSS3 :target pseudo selector and the .target class selector together in the same rule set, but I found that Opera (9.26) would not apply the rules presumably because it considered it invalid.
/* THIS DOES NOT WORK! */
h2:target,
h2.target {
color: red;
}
I’m not sure if this is correct behavior, but regardless of cause, I found I had to use a duplicate set of CSS rules; one for both modes of selection.
h2:target {
color: red;
}
h2.target {
color: red;
}
And basically… that’s it! You can see it in action on this test page, and I hope to add a follow up post soon…. time allowing.
You download the the JavaScript here:
Full-fat script with white-space and comments [1621 bytes]
Minified script [1101 bytes]