We all know what a pain it can be to design certain elements, like tabs or menu graphics, that can expand to suit any length of input. Of course, we do our best to accomodate, but some content is just too long to look good.
My solution to this is TextScroller - you give it a list of elements to parse, and if any of them have text longer than a threshold amount, it will truncate the text with ‘…’ But that’s not all. When the user mouses over, the text will seem to ’scroll’ through the element until the entire string has been displayed.
Features:
Example:
The text in the box above is too long to fit in the box. Click below to turn on TextScroller
/** * @author David Baltusavich * @license GPLv2 * @copyright 2008 SynaTree Internet Growth Strategies, all rights reserved. * * TextScroller, a simple routine to truncate and scroll long strings inside elements. */
TextScroller = new Class({
/**
* Create a scroller if the content in the target node is sufficiently long.
* @param {DOMNode} node
* @param {Integer} maxLen, the maximum length of textContent before triggering the routine
* @param {Integer} increment, the number of characters to consume each iteration
* @param {Integer} rate, a timer number that is the basis for the periodical and delays.
*/
initialize: function(node, maxLen, increment, rate){
var bLong = false;
var bActing = false;
increment = increment || 3;
maxLen = maxLen || 50;
rate = rate || 200;
var pauserate = rate * 3;
var trumaxLen = maxLen - 3;
var timers = {start: false, end: false};
var ticker = 0;
var reset = function(){
node.set('text', cache.slice(0, trumaxLen) + '...');
ticker = 0;
};
if(node.get('text').length > maxLen )
{
bLong = true;
var cache = node.get('text');
reset();
}
if(bLong)
{
var start = function(){
ticker += increment;
// if we are not yet at the end, show a little more of the string.
var bEnough = cache.length > ticker+trumaxLen;
// if there is still even more, keep the dots, otherwise, just show the whole string.
node.set('text', bEnough ? cache.slice(ticker, ticker+trumaxLen) + '...' : cache.slice(ticker) );
if(!bEnough)
// we've come to the end, stop calling the scroller.
$clear(timers.start);
};
node.addEvent('mouseover', function(){
// cancel any pending reset timer
if(timers.end)
{
$clear(timers.end);
delete timers.end;
}
// start the scroller
if(!timers.start)
{
timers.start = start.periodical(rate);
}
} );
node.addEvent('mouseout', function(){
// wait a moment in case the user get back inside the box, then reset the text to it's original state.
if(timers.start)
{
timers.end = (function(){
$clear( timers.start );
delete timers.start;
reset();
}).delay(pauserate);
}
} );
}
}
});
/**
* A handy utility to scan a collection of elements
* @param {Collection} coll, a collection of Nodes.
* @param {Integer} maxLength, the maximum allowed length of textContent
* @param {Integer} time, basic timer interval (speed)
* @param {Integer} increment, the number of characters to consume with each iteration
* @returns {Array} array of scroller objects.
*/
TextScroller.scanElements = function( coll, maxLength, time, increment)
{
var scrollers = [];
maxLength = maxLength || 50;
time = time || 200;
increment = increment || 3;
if(coll.each)
coll.each(function(item){
scrollers.push( new TextScroller(item, maxLength, increment, time) );
});
return scrollers;
};