PageSourceSearch

https://inpress.ua/js/jquery.ticker.js

js inpress.ua collected 2026-10-02 15:10:59 UTC 15,931 bytes, 430 lines download raw bytes

1/*
2    jQuery News Ticker is free software: you can redistribute it and/or modify
3    it under the terms of the GNU General Public License as published by
4    the Free Software Foundation, version 2 of the License.
5
6    jQuery News Ticker is distributed in the hope that it will be useful,
7    but WITHOUT ANY WARRANTY; without even the implied warranty of
8    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9    GNU General Public License for more details.
10
11    You should have received a copy of the GNU General Public License
12    along with jQuery News Ticker.  If not, see <http://www.gnu.org/licenses/>.
13*/
14(function($){
15	$.fn.ticker = function(options) {
16		// Extend our default options with those provided.
17		// Note that the first arg to extend is an empty object -
18		// this is to keep from overriding our "defaults" object.
19		var opts = $.extend({}, $.fn.ticker.defaults, options);
20
21		// check that the passed element is actually in the DOM
22		if ($(this).length == 0) {
23			if (window.console && window.console.log) {
24				window.console.log('Element does not exist in DOM!');
25			}
26			else {
27				alert('Element does not exist in DOM!');
28			}
29			return false;
30		}
31
32		/* Get the id of the UL to get our news content from */
33		var newsID = '#' + $(this).attr('id');
34
35		/* Get the tag type - we will check this later to makde sure it is a UL tag */
36		var tagType = $(this).get(0).tagName;
37
38		return this.each(function() {
39			// get a unique id for this ticker
40			var uniqID = getUniqID();
41
42			/* Internal vars */
43			var settings = {
44				position: 0,
45				time: 0,
46				distance: 0,
47				newsArr: {},
48				play: true,
49				paused: false,
50				contentLoaded: false,
51				dom: {
52					contentID: '#ticker-content-' + uniqID,
53					titleID: '#ticker-title-' + uniqID,
54					titleElem: '#ticker-title-' + uniqID + ' SPAN',
55					tickerID : '#ticker-' + uniqID,
56					wrapperID: '#ticker-wrapper-' + uniqID,
57					revealID: '#ticker-swipe-' + uniqID,
58					revealElem: '#ticker-swipe-' + uniqID + ' SPAN',
59					controlsID: '#ticker-controls-' + uniqID,
60					prevID: '#prev-' + uniqID,
61					nextID: '#next-' + uniqID,
62					playPauseID: '#play-pause-' + uniqID
63				}
64			};
65
66			// if we are not using a UL, display an error message and stop any further execution
67			if (tagType != 'UL' && tagType != 'OL' && opts.htmlFeed === true) {
68				debugError('Cannot use <' + tagType.toLowerCase() + '> type of element for this plugin - must of type <ul> or <ol>');
69				return false;
70			}
71
72			// set the ticker direction
73			opts.direction == 'rtl' ? opts.direction = 'right' : opts.direction = 'left';
74
75			// lets go...
76			initialisePage();
77			/* Function to get the size of an Object*/
78			function countSize(obj) {
79			    var size = 0, key;
80			    for (key in obj) {
81			        if (obj.hasOwnProperty(key)) size++;
82			    }
83			    return size;
84			};
85
86			function getUniqID() {
87				var newDate = new Date;
88				return newDate.getTime();
89			}
90
91			/* Function for handling debug and error messages */
92			function debugError(obj) {
93				if (opts.debugMode) {
94					if (window.console && window.console.log) {
95						window.console.log(obj);
96					}
97					else {
98						alert(obj);
99					}
100				}
101			}
102
103			/* Function to setup the page */
104			function initialisePage() {
105				// process the content for this ticker
106				processContent();
107
108				// add our HTML structure for the ticker to the DOM
109				$(newsID).wrap('<div id="' + settings.dom.wrapperID.replace('#', '') + '"></div>');
110
111				// remove any current content inside this ticker
112				$(settings.dom.wrapperID).children().remove();
113
114				$(settings.dom.wrapperID).append('<div id="' + settings.dom.tickerID.replace('#', '') + '" class="ticker"><div id="' + settings.dom.titleID.replace('#', '') + '" class="ticker-title"><span><!-- --></span></div><p id="' + settings.dom.contentID.replace('#', '') + '" class="ticker-content"></p><div id="' + settings.dom.revealID.replace('#', '') + '" class="ticker-swipe"><span><!-- --></span></div></div>');
115				$(settings.dom.wrapperID).removeClass('no-js').addClass('ticker-wrapper has-js ' + opts.direction);
116				// hide the ticker
117				$(settings.dom.tickerElem + ',' + settings.dom.contentID).hide();
118				// add the controls to the DOM if required
119				if (opts.controls) {
120					// add related events - set functions to run on given event
121					$(settings.dom.controlsID).live('click mouseover mousedown mouseout mouseup', function (e) {
122						var button = e.target.id;
123						if (e.type == 'click') {
124							switch (button) {
125								case settings.dom.prevID.replace('#', ''):
126									// show previous item
127									settings.paused = true;
128									$(settings.dom.playPauseID).addClass('paused');
129									manualChangeContent('prev');
130									break;
131								case settings.dom.nextID.replace('#', ''):
132									// show next item
133									settings.paused = true;
134									$(settings.dom.playPauseID).addClass('paused');
135									manualChangeContent('next');
136									break;
137								case settings.dom.playPauseID.replace('#', ''):
138									// play or pause the ticker
139									if (settings.play == true) {
140										settings.paused = true;
141										$(settings.dom.playPauseID).addClass('paused');
142										pauseTicker();
143									}
144									else {
145										settings.paused = false;
146										$(settings.dom.playPauseID).removeClass('paused');
147										restartTicker();
148									}
149									break;
150							}
151						}
152						else if (e.type == 'mouseover' && $('#' + button).hasClass('controls')) {
153							$('#' + button).addClass('over');
154						}
155						else if (e.type == 'mousedown' && $('#' + button).hasClass('controls')) {
156							$('#' + button).addClass('down');
157						}
158						else if (e.type == 'mouseup' && $('#' + button).hasClass('controls')) {
159							$('#' + button).removeClass('down');
160						}
161						else if (e.type == 'mouseout' && $('#' + button).hasClass('controls')) {
162							$('#' + button).removeClass('over');
163						}
164					});
165					// add controls HTML to DOM
166					$(settings.dom.wrapperID).append('<ul id="' + settings.dom.controlsID.replace('#', '') + '" class="ticker-controls"><li id="' + settings.dom.prevID.replace('#', '') + '" class="jnt-prev png_bg controls"><a href=""><!-- --></a></li><li id="' + settings.dom.playPauseID.replace('#', '') + '" class="jnt-play-pause png_bg controls"><a href=""><!-- --></a></li><li id="' + settings.dom.nextID.replace('#', '') + '" class="jnt-next png_bg controls"><a href=""><!-- --></a></li></ul>');
167				}
168				if (opts.displayType != 'fade') {
169                	// add mouse over on the content
170               		$(settings.dom.contentID).mouseover(function () {
171               			if (settings.paused == false) {
172               				pauseTicker();
173               			}
174               		}).mouseout(function () {
175               			if (settings.paused == false) {
176               				restartTicker();
177               			}
178               		});
179				}
180				// we may have to wait for the ajax call to finish here
181				if (!opts.ajaxFeed) {
182					setupContentAndTriggerDisplay();
183				}
184			}
185
186			/* Start to process the content for this ticker */
187			function processContent() {
188				// check to see if we need to load content
189				if (settings.contentLoaded == false) {
190					// construct content
191					if (opts.ajaxFeed) {
192						if (opts.feedType == 'xml') {
193							$.ajax({
194								url: opts.feedUrl,
195								cache: false,
196								dataType: opts.feedType,
197								async: true,
198								success: function(data){
199									count = 0;
200									// get the 'root' node
201									for (var a = 0; a < data.childNodes.length; a++) {
202										if (data.childNodes[a].nodeName == 'rss') {
203											xmlContent = data.childNodes[a];
204										}
205									}
206									// find the channel node
207									for (var i = 0; i < xmlContent.childNodes.length; i++) {
208										if (xmlContent.childNodes[i].nodeName == 'channel') {
209											xmlChannel = xmlContent.childNodes[i];
210										}
211									}
212									// for each item create a link and add the article title as the link text
213									for (var x = 0; x < xmlChannel.childNodes.length; x++) {
214										if (xmlChannel.childNodes[x].nodeName == 'item') {
215											xmlItems = xmlChannel.childNodes[x];
216											var title, link = false;
217											for (var y = 0; y < xmlItems.childNodes.length; y++) {
218												if (xmlItems.childNodes[y].nodeName == 'title') {
219													title = xmlItems.childNodes[y].lastChild.nodeValue;
220												}
221												else if (xmlItems.childNodes[y].nodeName == 'link') {
222													link = xmlItems.childNodes[y].lastChild.nodeValue;
223												}
224												if ((title !== false && title != '') && link !== false) {
225												    settings.newsArr['item-' + count] = { type: opts.titleText, content: '<a href="' + link + '">' + title + '</a>' };												    count++;												    title = false;												    link = false;
226												}
227											}
228										}
229									}
230									// quick check here to see if we actually have any content - log error if not
231									if (countSize(settings.newsArr < 1)) {
232										debugError('Couldn\'t find any content from the XML feed for the ticker to use!');
233										return false;
234									}
235									settings.contentLoaded = true;
236									setupContentAndTriggerDisplay();
237								}
238							});
239						}
240						else {
241							debugError('Code Me!');
242						}
243					}
244					else if (opts.htmlFeed) {
245						if($(newsID + ' LI').length > 0) {
246							$(newsID + ' LI').each(function (i) {
247								// maybe this could be one whole object and not an array of objects?
248								settings.newsArr['item-' + i] = { type: opts.titleText, content: $(this).html()};
249							});
250						}
251						else {
252							debugError('Couldn\'t find HTML any content for the ticker to use!');
253							return false;
254						}
255					}
256					else {
257						debugError('The ticker is set to not use any types of content! Check the settings for the ticker.');
258						return false;
259					}
260				}
261			}
262
263			function setupContentAndTriggerDisplay() {
264
265				settings.contentLoaded = true;
266
267				// update the ticker content with the correct item
268				// insert news content into DOM
269				$(settings.dom.titleElem).html(settings.newsArr['item-' + settings.position].type);
270				$(settings.dom.contentID).html(settings.newsArr['item-' + settings.position].content);
271
272				// set the next content item to be used - loop round if we are at the end of the content
273				if (settings.position == (countSize(settings.newsArr) -1)) {
274					settings.position = 0;
275				}
276				else {
277					settings.position++;
278				}
279
280				// get the values of content and set the time of the reveal (so all reveals have the same speed regardless of content size)
281				distance = $(settings.dom.contentID).width();
282				time = distance / opts.speed;
283
284				// start the ticker animation
285				revealContent();
286			}
287
288			// slide back cover or fade in content
289			function revealContent() {
290				$(settings.dom.contentID).css('opacity', '1');
291				if(settings.play) {
292					// get the width of the title element to offset the content and reveal
293					var offset = $(settings.dom.titleID).width() + 20;
294
295					$(settings.dom.revealID).css(opts.direction, offset + 'px');
296					// show the reveal element and start the animation
297					if (opts.displayType == 'fade') {
298						// fade in effect ticker
299						$(settings.dom.revealID).hide(0, function () {
300							$(settings.dom.contentID).css(opts.direction, offset + 'px').fadeIn(opts.fadeInSpeed, postReveal);
301						});
302					}
303					else if (opts.displayType == 'scroll') {
304						// to code
305            $(settings.dom.revealElem).show(0, function () {
306              $(settings.dom.contentID).css(opts.direction, offset + 'px').show();
307            });
308					}
309					else {
310						// default bbc scroll effect
311						$(settings.dom.revealElem).show(0, function () {
312							$(settings.dom.contentID).css(opts.direction, offset + 'px').show();
313							// set our animation direction
314							animationAction = opts.direction == 'right' ? { marginRight: distance + 'px'} : { marginLeft: distance + 'px' };
315							$(settings.dom.revealID).css('margin-' + opts.direction, '0px').delay(20).animate(animationAction, time, 'linear', postReveal);
316						});
317					}
318				}
319				else {
320					return false;
321				}
322			};
323
324			// here we hide the current content and reset the ticker elements to a default state ready for the next ticker item
325			function postReveal() {
326				if(settings.play) {
327					// we have to separately fade the content out here to get around an IE bug - needs further investigation
328					$(settings.dom.contentID).delay(opts.pauseOnItems).fadeOut(opts.fadeOutSpeed);
329					// deal with the rest of the content, prepare the DOM and trigger the next ticker
330					if (opts.displayType == 'fade') {
331						$(settings.dom.contentID).fadeOut(opts.fadeOutSpeed, function () {
332							$(settings.dom.wrapperID)
333								.find(settings.dom.revealElem + ',' + settings.dom.contentID)
334									.hide()
335								.end().find(settings.dom.tickerID + ',' + settings.dom.revealID)
336									.show()
337								.end().find(settings.dom.tickerID + ',' + settings.dom.revealID)
338									.removeAttr('style');
339							setupContentAndTriggerDisplay();
340						});
341					}
342					else {
343						$(settings.dom.revealID).hide(0, function () {
344							$(settings.dom.contentID).fadeOut(opts.fadeOutSpeed, function () {
345								$(settings.dom.wrapperID)
346									.find(settings.dom.revealElem + ',' + settings.dom.contentID)
347										.hide()
348									.end().find(settings.dom.tickerID + ',' + settings.dom.revealID)
349										.show()
350									.end().find(settings.dom.tickerID + ',' + settings.dom.revealID)
351										.removeAttr('style');
352								setupContentAndTriggerDisplay();
353							});
354						});
355					}
356				}
357				else {
358					$(settings.dom.revealElem).hide();
359				}
360			}
361
362			// pause ticker
363			function pauseTicker() {
364				settings.play = false;
365				// stop animation and show content - must pass "true, true" to the stop function, or we can get some funky behaviour
366				$(settings.dom.tickerID + ',' + settings.dom.revealID + ',' + settings.dom.titleID + ',' + settings.dom.titleElem + ',' + settings.dom.revealElem + ',' + settings.dom.contentID).stop(true, true);
367				$(settings.dom.revealID + ',' + settings.dom.revealElem).hide();
368				$(settings.dom.wrapperID)
369					.find(settings.dom.titleID + ',' + settings.dom.titleElem).show()
370						.end().find(settings.dom.contentID).show();
371			}
372
373			// play ticker
374			function restartTicker() {
375				settings.play = true;
376				settings.paused = false;
377				// start the ticker again
378				postReveal();
379			}
380
381			// change the content on user input
382			function manualChangeContent(direction) {
383				pauseTicker();
384				switch (direction) {
385					case 'prev':
386						if (settings.position == 0) {
387							settings.position = countSize(settings.newsArr) -2;
388						}
389						else if (settings.position == 1) {
390							settings.position = countSize(settings.newsArr) -1;
391						}
392						else {
393							settings.position = settings.position - 2;
394						}
395						$(settings.dom.titleElem).html(settings.newsArr['item-' + settings.position].type);
396						$(settings.dom.contentID).html(settings.newsArr['item-' + settings.position].content);
397						break;
398					case 'next':
399						$(settings.dom.titleElem).html(settings.newsArr['item-' + settings.position].type);
400						$(settings.dom.contentID).html(settings.newsArr['item-' + settings.position].content);
401						break;
402				}
403				// set the next content item to be used - loop round if we are at the end of the content
404				if (settings.position == (countSize(settings.newsArr) -1)) {
405					settings.position = 0;
406				}
407				else {
408					settings.position++;
409				}
410			}
411		});
412	};
413
414	// plugin defaults - added as a property on our plugin function
415	$.fn.ticker.defaults = {
416		speed: 0.10,
417		ajaxFeed: false,
418		feedUrl: '',
419		feedType: 'xml',
420		displayType: 'reveal',
421		htmlFeed: true,
422		debugMode: true,
423		controls: true,
424		titleText: 'Latest',
425		direction: 'ltr',
426		pauseOnItems: 3000,
427		fadeInSpeed: 600,
428		fadeOutSpeed: 300
429	};
430})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.