master
Raw Download raw file
  1/*!
  2 * webTicker 2.1.1
  3 * Examples and documentation at:
  4 * http://jonmifsud.com/open-source/jquery/jquery-webticker/
  5 * 2011 Jonathan Mifsud
  6 * Version: 2.1.1 (23-MAY-2013)
  7 * Dual licensed under the Creative Commons and DonationWare licenses:
  8 * http://creativecommons.org/licenses/by-nc/3.0/
  9 * https://github.com/jonmifsud/Web-Ticker/blob/master/licence.md
 10 * Requires:
 11 * jQuery v1.4.2 or later
 12 *
 13 */
 14(function( $ ){
 15
 16	var cssTransitionsSupported = (function() {
 17	    var s = document.createElement('p').style,
 18	        v = ['ms','O','Moz','Webkit'];
 19
 20	    if( s['transition'] == '' ) return true;
 21	    while( v.length )
 22	        if( v.pop() + 'Transition' in s )
 23	            return true;
 24	    return false;
 25	})();
 26
 27	function scrollitems($strip,moveFirst){
 28		var settings = $strip.data('settings') || { direction: "left" };
 29		if (typeof moveFirst === 'undefined')
 30			moveFirst = false;
 31		if (moveFirst){
 32			moveFirstElement($strip);
 33		}
 34		var options = animationSettings($strip);
 35		$strip.animate(options.css, options.time, "linear", function(){
 36			$strip.css(settings.direction, '0');
 37			scrollitems($strip,true);
 38		});
 39	}
 40
 41	function animationSettings($strip){
 42		var settings = $strip.data('settings') || { direction: "left", speed: 50 };
 43		var first = $strip.children().first();
 44		var distance =  Math.abs(-$strip.css(settings.direction).replace('px','').replace('auto','0') - first.outerWidth(true));
 45		var settings = $strip.data('settings');
 46		var timeToComplete = distance * 1000 / settings.speed;
 47		var animationSettings = {};
 48		animationSettings[settings.direction] = $strip.css(settings.direction).replace('px','').replace('auto','0') - distance;
 49		return {'css':animationSettings,'time':timeToComplete};
 50	}
 51
 52	function moveFirstElement($strip){
 53		var settings = $strip.data('settings') || { direction: "left" };
 54		$strip.css('transition-duration','0s').css(settings.direction, '0');
 55		var $first = $strip.children().first();
 56		if ($first.hasClass('webticker-init'))
 57			$first.remove();
 58		else
 59			$strip.children().last().after($first);
 60	}
 61
 62	function css3Scroll($strip,moveFirst){
 63		if (typeof moveFirst === 'undefined')
 64			moveFirst = false;
 65		if (moveFirst){
 66			moveFirstElement($strip);
 67		}
 68		var options = animationSettings($strip);
 69		var time = options.time/1000;
 70		time += 's';
 71		$strip.css(options.css).css('transition-duration',time);
 72	}
 73
 74	function updaterss(rssurl,type,$strip){
 75		var list = [];
 76		$.get(rssurl, function(data) {
 77		    var $xml = $(data);
 78		    $xml.find("item").each(function() {
 79		        var $this = $(this),
 80		            item = {
 81		                title: $this.find("title").text(),
 82		                link: $this.find("link").text()
 83		        }
 84		        listItem = "<li><a href='"+item.link+"'>"+item.title+"</a></li>";
 85		        list += listItem;
 86		        //Do something with item here...
 87		    });
 88			$strip.webTicker('update', list, type);
 89		});
 90	}
 91
 92	function initalize($strip){
 93		if ($strip.children('li').length < 1) {
 94			if (window.console) {
 95				console.log('no items to initialize');
 96			}
 97			return false;
 98		}
 99
100		var settings = $strip.data('settings');
101		settings.duplicateLoops = settings.duplicateLoops || 0;
102
103		$strip.width('auto');
104
105		//Find the real width of all li elements
106		var stripWidth = 0;
107		$strip.children('li').each(function(){
108			stripWidth += $(this).outerWidth( true );
109		});
110
111		if(stripWidth < $strip.parent().width() || $strip.children().length == 1){
112			//if duplicate items
113			if (settings.duplicate){
114				//Check how many times to duplicate depending on width.
115				itemWidth = Math.max.apply(Math, $strip.children().map(function(){ return $(this).width(); }).get());
116				var duplicateLoops = 0;
117				while (stripWidth - itemWidth < $strip.parent().width() || $strip.children().length == 1 || duplicateLoops < settings.duplicateLoops){
118					var listItems = $strip.children().clone();
119					$strip.append(listItems);
120					stripWidth = 0;
121					$strip.children('li').each(function(){
122						stripWidth += $(this).outerWidth( true );
123					});
124					itemWidth = Math.max.apply(Math, $strip.children().map(function(){ return $(this).width(); }).get());
125					duplicateLoops++;
126				}
127				settings.duplicateLoops = duplicateLoops;
128			}else {
129				//if fill with empty padding
130				var emptySpace = $strip.parent().width() - stripWidth;
131				emptySpace += $strip.find("li:first").width();
132				var height = $strip.find("li:first").height();
133
134				$strip.append('<li class="ticker-spacer" style="width:'+emptySpace+'px;height:'+height+'px;"></li>');
135			}
136		}
137		if (settings.startEmpty){
138			var height = $strip.find("li:first").height();
139			$strip.prepend('<li class="webticker-init" style="width:'+$strip.parent().width()+'px;height:'+height+'px;"></li>');
140		}
141		//extra width to be able to move items without any jumps	$strip.find("li:first").width()
142
143		stripWidth = 0;
144		$strip.children('li').each(function(){
145			stripWidth += $(this).outerWidth( true );
146		});
147		$strip.width(stripWidth+200);
148		widthCompare = 0;
149		$strip.children('li').each(function(){
150			widthCompare += $(this).outerWidth( true );
151		});
152		//loop to find weather the items inside the list are actually bigger then the size of the whole list. Increments in 200px.
153		//only required when a single item is bigger then the whole list
154		while (widthCompare >= $strip.width()){
155			$strip.width($strip.width()+200);
156			widthCompare = 0;
157			$strip.children('li').each(function(){
158				widthCompare += $(this).outerWidth( true );
159			});
160		}
161		return true;
162	}
163
164  var methods = {
165    init : function( settings ) { // THIS
166		settings = jQuery.extend({
167			speed: 50, //pixels per second
168			direction: "left",
169			moving: true,
170			startEmpty: true,
171			duplicate: false,
172			rssurl: false,
173			hoverpause: true,
174			rssfrequency: 0,
175			updatetype: "reset"
176		}, settings);
177		//set data-ticker a unique ticker identifier if it does not exist
178		return this.each(function(){
179			jQuery(this).data('settings',settings);
180
181				var $strip = jQuery(this);
182				$strip.addClass("newsticker");
183				var $mask = $strip.wrap("<div class='mask'></div>");
184				$mask.after("<span class='tickeroverlay-left'>&nbsp;</span><span class='tickeroverlay-right'>&nbsp;</span>")
185				var $tickercontainer = $strip.parent().wrap("<div class='tickercontainer'></div>");
186
187				var started = initalize($strip);
188
189				if (settings.rssurl){
190					updaterss(settings.rssurl,settings.type,$strip);
191					if (settings.rssfrequency>0){
192						window.setInterval(function(){updaterss(settings.rssurl,settings.type,$strip);},settings.rssfrequency*1000*60);
193					}
194				}
195
196				if (cssTransitionsSupported){
197					//fix for firefox not animating default transitions
198					$strip.css('transition-duration','0s').css(settings.direction, '0');
199
200					if (started){
201						//if list has items and set up start scrolling
202						css3Scroll($strip,false);
203					}
204					//started or not still bind on the transition end event so it works after update
205					$strip.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend', function(event) {
206						if (!$strip.is(event.target)) {
207							return false;
208						}
209						css3Scroll($(this),true);
210					});
211				} else {
212					if (started){
213						//if list has items and set up start scrolling
214						scrollitems($(this));
215					}
216				}
217
218				if (settings.hoverpause){
219					$strip.hover(function(){
220						if (cssTransitionsSupported){
221							var currentPosition = $(this).css(settings.direction);
222							$(this).css('transition-duration','0s').css(settings.direction,currentPosition);
223						} else
224							jQuery(this).stop();
225					},
226					function(){
227						if (jQuery(this).data('settings').moving){
228							if (cssTransitionsSupported){
229								css3Scroll($(this),false);
230								// $(this).css("-webkit-animation-play-state", "running");
231							} else {
232								//usual continue stuff
233								scrollitems($strip);
234							}
235						}
236					});
237				}
238		});
239	},
240    stop : function( ) {
241    	var settings = $(this).data('settings');
242		if (settings.moving){
243			settings.moving = false;
244			return this.each(function(){
245				if (cssTransitionsSupported){
246					var currentPosition = $(this).css(settings.direction);
247					$(this).css('transition-duration','0s').css(settings.direction,currentPosition);
248				} else
249					$(this).stop();
250			});
251		}
252	},
253    cont : function( ) {
254    	var settings = $(this).data('settings')
255		if (!settings.moving){
256			settings.moving = true;
257			return this.each(function(){
258				if (cssTransitionsSupported){
259					css3Scroll($(this),false);
260				} else {
261					scrollitems($(this));
262				}
263			});
264		}
265	},
266	update : function( list, type, insert, remove) {
267		type = type || "reset";
268		if (typeof insert === 'undefined')
269			insert = true;
270		if (typeof remove === 'undefined')
271			remove = false;
272		if( typeof list === 'string' ) {
273		    list = $(list);
274		}
275		var $strip = $(this);
276		$strip.webTicker('stop');
277		var settings = $(this).data('settings');
278		if (type == 'reset'){
279			//this does a 'restart of the ticker'
280			$strip.html(list);
281			$strip.css(settings.direction, '0');
282			initalize($strip);
283		} else if (type == 'swap'){
284			if (window.console) {
285				console.log('trying to update');
286			}
287			if ($strip.children('li').length < 1){
288				//there were no items treat as if new
289				$strip.html(list);
290				$strip.css(settings.direction, '0');
291				initalize($strip);
292			} else {
293				// should the update be a 'hot-swap' or use replacement for IDs (in which case remove new ones)
294				$strip.children('li').addClass('old');
295				for (var i = 0; i < list.length; i++) {
296					id = $(list[i]).data('update');
297					match = $strip.find('[data-update="'+id+'"]');//should try find the id or data-attribute.
298					if (match.length < 1){
299						if (insert){
300							//we need to move this item into the dom
301							if ($strip.find('.ticker-spacer:first-child').length == 0 && $strip.find('.ticker-spacer').length > 0){
302								$strip.children('li.ticker-spacer').before(list[i]);
303							}
304							else {
305								$strip.append(list[i]);
306							}
307						}
308					} else $strip.find('[data-update="'+id+'"]').replaceWith(list[i]);;
309				};
310				$strip.children('li.webticker-init, li.ticker-spacer').removeClass('old');
311				if (remove)
312					$strip.children('li').remove('.old');
313				stripWidth = 0;
314				$strip.children('li').each(function(){
315					stripWidth += $(this).outerWidth( true );
316				});
317				$strip.width(stripWidth+200);
318			}
319		}
320
321		$strip.webTicker('cont');
322	}
323  };
324
325  $.fn.webTicker = function( method ) {
326
327    // Method calling logic
328    if ( methods[method] ) {
329      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
330    } else if ( typeof method === 'object' || ! method ) {
331      return methods.init.apply( this, arguments );
332    } else {
333      $.error( 'Method ' +  method + ' does not exist on jQuery.webTicker' );
334    }
335
336  };
337
338})( jQuery );