/* News ticker plugin (BBC news style) Bryan Gullan,2007-2010 version 2.2 updated 2010-04-04 Documentation at http://www.makemineatriple.com/news-ticker-documentation/ Demo at http://www.makemineatriple.com/jquery/?newsTicker Use and distrubute freely with this header intact. */ (function($) { var name='newsTicker'; function runTicker(settings) { tickerData = $(settings.newsList).data('newsTicker'); if(tickerData.currentItem > tickerData.newsItemCounter){ // if we've looped to beyond the last item in the list, start over tickerData.currentItem = 0; } else if (tickerData.currentItem < 0) { // if we've looped back before the first item, move to the last one tickerData.currentItem = tickerData.newsItemCounter; } if(tickerData.currentPosition == 0) { if(tickerData.newsLinks[tickerData.currentItem].length > 0) { $(tickerData.newsList).empty().append('
  • '); } else { $(tickerData.newsList).empty().append('
  • '); } } //only start the ticker itself if it's defined as animating: otherwise it's paused or under manual advance if (tickerData.animating) { if( tickerData.currentPosition % 2 == 0) { var placeHolder = tickerData.placeHolder1; } else { var placeHolder = tickerData.placeHolder2; } if( tickerData.currentPosition < tickerData.newsItems[tickerData.currentItem].length) { // we haven't completed ticking out the current item var tickerText = tickerData.newsItems[tickerData.currentItem].substring(0,tickerData.currentPosition); if(tickerData.newsLinks[tickerData.currentItem].length > 0) { $(tickerData.newsList + ' li a').text(tickerText + placeHolder); } else { $(tickerData.newsList + ' li').text(tickerText + placeHolder); } tickerData.currentPosition ++; setTimeout(function(){runTicker(settings); settings = null;},tickerData.tickerRate); } else { // we're on the last letter of the current item if(tickerData.newsLinks[tickerData.currentItem].length > 0) { $(tickerData.newsList + ' li a').text(tickerData.newsItems[tickerData.currentItem]); } else { $(tickerData.newsList + ' li').text(tickerData.newsItems[tickerData.currentItem]); } setTimeout(function(){ if (tickerData.animating) { tickerData.currentPosition = 0; tickerData.currentItem ++; runTicker(settings); settings = null; } },tickerData.loopDelay); } } else {// settings.animating == false // display the full text of the current item var tickerText = tickerData.newsItems[tickerData.currentItem]; if(tickerData.newsLinks[tickerData.currentItem].length > 0) { $(tickerData.newsList + ' li a').text(tickerText); } else { $(tickerData.newsList + ' li').text(tickerText); } } } // Core plugin setup and config jQuery.fn[name] = function(options) { // Add or overwrite options onto defaults var settings = jQuery.extend({}, jQuery.fn.newsTicker.defaults, options); var newsItems = new Array(); var newsLinks = new Array(); var newsItemCounter = 0; // Hide the static list items $(settings.newsList + ' li').hide(); // Store the items and links in arrays for output $(settings.newsList + ' li').each(function(){ if($(this).children('a').length) { newsItems[newsItemCounter] = $(this).children('a').text(); newsLinks[newsItemCounter] = $(this).children('a').attr('href'); } else { newsItems[newsItemCounter] = $(this).text(); newsLinks[newsItemCounter] = ''; } newsItemCounter ++; }); var tickerElement = $(settings.newsList); // for quick reference below tickerElement.data(name, { newsList: settings.newsList, tickerRate: settings.tickerRate, startDelay: settings.startDelay, loopDelay: settings.loopDelay, placeHolder1: settings.placeHolder1, placeHolder2: settings.placeHolder2, controls: settings.controls, ownControls: settings.ownControls, stopOnHover: settings.stopOnHover, newsItems: newsItems, newsLinks: newsLinks, newsItemCounter: newsItemCounter - 1, // -1 because we've incremented even after the last item (above) currentItem: 0, currentPosition: 0, firstRun:1 }) .bind({ stop: function(event) { // show remainder of the current item immediately tickerData = tickerElement.data(name); if (tickerData.animating) { // only stop if not already stopped tickerData.animating = false; } }, play: function(event) { // show 1st item with startdelay tickerData = tickerElement.data(name); if (!tickerData.animating) { // if already animating, don't start animating again tickerData.animating = true; setTimeout(function(){runTicker(tickerData); tickerData = null;},tickerData.startDelay); } }, resume: function(event) { // start from next item, with no delay tickerData = tickerElement.data(name); if (!tickerData.animating) { // if already animating, don't start animating again tickerData.animating = true; // set the character position as 0 to ensure on resume we start at the right point tickerData.currentPosition = 0; tickerData.currentItem ++; runTicker(tickerData); // no delay when resuming. } }, next: function(event) { // show whole of next item tickerData = tickerElement.data(name); // stop (which sets as non-animating), and call runticker $(tickerData.newsList).trigger("stop"); // set the character position as 0 to ensure on resume we start at the right point tickerData.currentPosition = 0; tickerData.currentItem ++; runTicker(tickerData); }, previous: function(event) { // show whole of previous item tickerData = tickerElement.data(name); // stop (which sets as non-animating), and call runticker $(tickerData.newsList).trigger("stop"); // set the character position as 0 to ensure on resume we start at the right point tickerData.currentPosition = 0; tickerData.currentItem --; runTicker(tickerData); } }); if (settings.stopOnHover) { tickerElement.bind({ mouseover: function(event) { tickerData = tickerElement.data(name); if (tickerData.animating) { // stop if not already stopped $(tickerData.newsList).trigger("stop"); if (tickerData.controls) { // ensure that the ticker can be resumed if controls are enabled $('.stop').hide(); $('.resume').show(); } } } }); } tickerData = tickerElement.data(name); // set up control buttons if the option is on if (tickerData.controls || tickerData.ownControls) { if (!tickerData.ownControls) { $('').insertAfter($(tickerData.newsList)); } $('.play').hide(); $('.resume').hide(); $('.play').click(function(event){ $(tickerData.newsList).trigger("play"); $('.play').hide(); $('.resume').hide(); $('.stop').show(); event.preventDefault(); }); $('.resume').click(function(event){ $(tickerData.newsList).trigger("resume"); $('.play').hide(); $('.resume').hide(); $('.stop').show(); event.preventDefault(); }); $('.stop').click(function(event){ $(tickerData.newsList).trigger("stop"); $('.stop').hide(); $('.resume').show(); event.preventDefault(); }); $('.previous').click(function(event){ $(tickerData.newsList).trigger("previous"); $('.stop').hide(); $('.resume').show(); event.preventDefault(); }); $('.next').click(function(event){ $(tickerData.newsList).trigger("next"); $('.stop').hide(); $('.resume').show(); event.preventDefault(); }); }; // tell it to play $(tickerData.newsList).trigger("play"); }; // News ticker defaults jQuery.fn[name].defaults = { newsList: "#news", tickerRate: 80, startDelay: 100, loopDelay: 3000, placeHolder1: " |", placeHolder2: "_", controls: true, ownControls: false, stopOnHover: true } })(jQuery);