nicetitle.js
/* This version of nicetitles was originally a mix between the
versions found at http://neo.dzygn.com/archive/2003/12/nicer-titles
and http://kryogenix.org/code/browser/nicetitle/. I've updated the
helper functions using some ideas from http://www.quirksmode.org,
rewritten or cleaned up most of the code and added some new
features.
Do not forget to add a version of the addEvent function somewhere.
Boris Yakobowski, October 2007
http://www.yakobowski.org/nicetitles.html
v1.0: initial release, April 2007
v1.1: corrected a viewport bug under Safari, October 2007
*/
var XHTMLNS = "http://www.w3.org/1999/xhtml";
function NiceTitles() {
if (!document.createElement || !document.getElementsByTagName) return;
// add namespace methods to HTML DOM; this makes the script work in both
// HTML and XML contexts.
if(!document.createElementNS) {
document.createElementNS = function(ns,elt) {
return document.createElement(elt);
}
}
var delay = 350;
initA();
initImg();
/* Internal variables */
var current_float;
var last_node = null;
var do_delay = true;
/* Initialization of the floating elements */
/* a tags with titles are displayed as nicetitles */
function initA () {
/* We do not use documents.links so as to see a tags with
empty href */
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
var lnk = links[i];
if (lnk.title) {
lnk.setAttribute('nicetitle', lnk.title);
lnk.removeAttribute('title');
attach_handlers(lnk);
}
}
}
/* img tags with class thumb are displayed as thumbnails */
function initImg() {
var imgs = document.getElementsByTagName("img");
for (var i=0; i<imgs.length; i++) {
var img = imgs[i];
if (img.className.match('thumb')) {
attach_handlers(img);
}
}
}
/* Handlers */
function attach_handlers(n) {
addEvent(n, "mouseover", showFloat);
addEvent(n, "focus", showFloat);
addEvent(n, "mouseout", hideFloat);
addEvent(n, "blur", hideFloat);
addEvent(n, "mousemove", repositionFloat);
}
function showFloat (e) {
if (current_float) hideFloat(current_float);
var d = document.createElementNS(XHTMLNS,"div");
if (this.nodeType == 1 && this.tagName == "IMG" &&
this.className.match('thumb'))
createThumbnail(d, this);
else
createNiceTitle(d, this);
/* We will display the floating element hidden, so that
we can compute its size and see if it fits within the window */
d.style.visibility = 'hidden';
/* We prevent the nicetitle from appearing at the bottom of
a document, which might temporarily create scroll bars */
d.style.top = '0px';
document.body.appendChild(d);
current_float = d;
positionFloat(e, this);
if (do_delay)
/* Displays the float with some delay */
setTimeout(function() {
d.style.visibility = 'visible';
do_delay=false;},
delay);
else
d.style.visibility = 'visible';
}
function repositionFloat(e){
positionFloat(e, this);
}
function hideFloat(e) {
if (current_float) {
document.body.removeChild(current_float);
current_float = null;
/* If no float is displayed for 300ms, we require
the following one to be displayed with a delay */
setTimeout(function() {
if (!current_float) do_delay=true;},
300);
}
}
/* Contents of the floating elements */
function createThumbnail (d, img) {
if (last_node != img) do_delay = true;
last_node = img;
d.className = "floating-thumb";
d.appendChild(img.cloneNode(false));
d.offset = {x : -25, y : 30};
}
function createNiceTitle (d, n) {
/* The focus can have been captured by a subnode (sup, em...)
of the 'a' node. We first retrieve the 'a' node itself */
lnk = getParent(n, "A");
if (last_node != lnk) do_delay = true;
last_node = lnk;
d.className = "nicetitle";
var p1 = document.createElementNS(XHTMLNS, "p");
p1.className = "titletext";
p1.appendChild(document.createTextNode(lnk.getAttribute("nicetitle")));
d.appendChild(p1);
/* If the link points to an url, we display it */
if (lnk.href) {
var p2 = document.createElementNS(XHTMLNS,"p");
p2.className = "destination";
p2.appendChild(document.createTextNode(lnk.href));
d.appendChild(p2);
} else if (lnk.name) {
/* Otherwise, we display the name of the lnk, if it exists */
var p2 = document.createElementNS(XHTMLNS,"p");
p2.className = "name";
p2.appendChild(document.createTextNode('#' + lnk.name));
d.appendChild(p2);
}
d.offset = {x : -15, y : 35};
}
/* Position of the floating elements */
function positionFloat(e, n){
if (!current_float) return;
var e = window.event ? window.event : e;
var viewport = getViewport();
/* Left top coordinates of the float, before any correction */
var float_lt;
if(e.type == "focus")
float_lt = getNodePosition(n);
else /* The event should be mouse-related */
float_lt = {x : viewport.x + e.clientX,
y : viewport.y + e.clientY};
var float_l = float_lt.x + current_float.offset.x;
var float_t = float_lt.y + current_float.offset.y;
/* Dimensions of the float */
var float_w = current_float.offsetWidth;
var float_h = current_float.offsetHeight;
/* Right down coordinates of the float, before corrections */
var float_r = float_l + float_w;
var float_d = float_t + float_h;
/* Coordinates of the right down corner of the window */
var window_r = viewport.width + viewport.x;
var window_d = viewport.height + viewport.y;
/* Correct the position if we overflow */
if(float_r + 10 >= window_r)
float_l = window_r - float_w - 10;
if(float_d + 10 >= window_d)
float_t = window_d - float_h - 10;
/* If the mouse is under the float, we shift it upwards */
if (e.type != "focus" &&
float_t-5 <= float_lt.y &&
float_lt.y <= float_t + float_h+5)
float_t = float_lt.y - float_h - 20;
current_float.style.left = float_l + "px";
current_float.style.top = float_t + "px";
}
}
addEvent(window, 'load', NiceTitles);
function getParent(el, pTagName) {
if (el == null) return null;
else if (el.nodeType == 1 && el.tagName == pTagName)
return el;
else
return getParent(el.parentNode, pTagName);
}
/* See http://www.quirksmode.org/viewport/intro.html and
http://www.quirksmode.org/viewport/compatibility.html */
function getViewport(){
var width = height = 0;
var x = y = 0;
if (self.innerHeight) { // all except Explorer
width = self.innerWidth;
height = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) {
// Explorer 6 Strict Mode
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
}
else if (document.body) { // other Explorers
width = document.body.clientWidth;
height = document.body.clientHeight;
}
if (self.pageYOffset) { // all except Explorer
x = self.pageXOffset;
y = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop) {
// Explorer 6 Strict
x = document.documentElement.scrollLeft;
y = document.documentElement.scrollTop;
} else if (document.body) { // all other Explorers
x = document.body.scrollLeft;
y = document.body.scrollTop;
}
return {width : width, height : height, x : x, y : y };
}
/* See http://www.quirksmode.org/js/findpos.html for some explanations */
function getNodePosition(obj){
var x = y = 0;
do {
if(obj.offsetLeft){x += obj.offsetLeft}
if(obj.offsetTop ){y += obj.offsetTop}
} while((obj = obj.offsetParent));
return {x : x, y : y};
}
Generated by GNU enscript 1.6.4.