eocjs-newsticker.js 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*!
  2. * eocjsNewsticker v0.6.1
  3. * Copyright (c) 2022 Dieter Schmitt
  4. * Released under the MIT license - https://opensource.org/licenses/MIT
  5. */
  6. (function($, window, document, undefined) {
  7. $.fn.eocjsNewsticker = function(options) {
  8. // _______ Options _______
  9. let defaults = {
  10. speed: 20,
  11. timeout: 1,
  12. divider: '+++',
  13. type: 'static', // static or ajax
  14. source: '', // ajax source (url)
  15. dataType: 'json', // data type of the expected file (json or jsonp)
  16. callback: 'callback', // used for jsonp
  17. fetch: false, // use fetch instead of $.ajax()
  18. interval: 120, // polling interval of the ajax source (seconds)
  19. direction: 'ltr' // direction (ltr or rtl)
  20. };
  21. let settings = $.extend({}, defaults, options);
  22. // _______ Inner Variables _______
  23. let self = this;
  24. let content = self.html();
  25. let active = 'eocjs-newsticker-active';
  26. let container = {};
  27. let one = {};
  28. let two = {};
  29. let both = {};
  30. let oneNeedsUpdate = false;
  31. let twoNeedsUpdate = false;
  32. let localWindow = $(window);
  33. let localWindowWidth = localWindow.width();
  34. // _______ Init _______
  35. function init() {
  36. if (!self.hasClass(active)) {
  37. create();
  38. start();
  39. self.addClass(active);
  40. }
  41. }
  42. // _______ Create _______
  43. function create() {
  44. self.addClass('eocjs-newsticker').html('<div class="eocjs-newsticker-container"><div class="eocjs-newsticker-one"></div><div class="eocjs-newsticker-two"></div></div>');
  45. container = self.find('.eocjs-newsticker-container');
  46. one = self.find('.eocjs-newsticker-one');
  47. two = self.find('.eocjs-newsticker-two');
  48. both = self.find('.eocjs-newsticker-one, .eocjs-newsticker-two');
  49. both.css({[convert('start')]: 0, [convert('end')]: 'auto'})
  50. }
  51. // _______ Start _______
  52. function start() {
  53. if (settings.type === 'static') {
  54. content = convert('prefix') + content + convert('suffix');
  55. run(content, (settings.timeout * 1000));
  56. } else if (settings.type === 'ajax') {
  57. container.prepend('<div class="eocjs-newsticker-loader"></div>');
  58. $.when(ajax(settings.source, settings.dataType, settings.callback, settings.fetch)).done(function(data) {
  59. setContent(data);
  60. container.find('.eocjs-newsticker-loader').fadeOut(300, function() {
  61. run(content, 0);
  62. $(this).remove();
  63. });
  64. setInterval(function() {
  65. $.when(ajax(settings.source, settings.dataType, settings.callback, settings.fetch)).done(function(data) {
  66. setContent(data);
  67. oneNeedsUpdate = true;
  68. twoNeedsUpdate = true;
  69. });
  70. }, settings.interval * 1000);
  71. });
  72. }
  73. }
  74. // _______ Additional function for LTR/RTL conversion _______
  75. function convert(type, data) {
  76. let addition = '';
  77. let dir = settings.direction;
  78. if (type === 'prefix') {
  79. data === undefined ? (dir !== 'rtl' ? addition = '' : addition = settings.divider + ' ') : (dir !== 'rtl' ? addition = data + ' ' : addition = settings.divider + ' ');
  80. } else if (type === 'suffix') {
  81. data === undefined ? (dir !== 'rtl' ? addition = ' ' + settings.divider : addition = '') : (dir !== 'rtl' ? addition = ' ' + settings.divider : addition = ' ' + data);
  82. } else if (type === 'start') {
  83. dir !== 'rtl' ? addition = 'left' : addition = 'right';
  84. } else if (type === 'end') {
  85. dir !== 'rtl' ? addition = 'right' : addition = 'left';
  86. } else if (type === 'update') {
  87. data === undefined ? (dir !== 'rtl' ? addition = 'append' : addition = 'prepend') : (dir !== 'rtl' ? addition = ' ' + data : addition = data + ' ');
  88. } else if (type === 'position') {
  89. addition = (dir !== 'rtl' && data.position().left > 0) || (dir === 'rtl' && (container.width() - (data.position().left + data.width())) > 0);
  90. }
  91. return addition;
  92. }
  93. // _______ Ajax _______
  94. function ajax(source, dataType, callback, useFetch) {
  95. if (dataType === 'json' && useFetch) {
  96. return fetch(source).then(function(response) {
  97. return response.json();
  98. });
  99. } else {
  100. return $.ajax({
  101. url: source,
  102. dataType: dataType,
  103. jsonpCallback: callback
  104. });
  105. }
  106. }
  107. // _______ setContent _______
  108. function setContent(data) {
  109. content = '';
  110. if ($.isPlainObject(data) && !$.isEmptyObject(data)) {
  111. for (let property in data) {
  112. if (data.hasOwnProperty(property)) {
  113. if (content === '') {
  114. content = convert('prefix') + data[property] + convert('suffix');
  115. } else {
  116. content = convert('prefix', content) + data[property] + convert('suffix', content);
  117. }
  118. }
  119. }
  120. } else if (Array.isArray(data) && data.length > 0) {
  121. for (let i = 0; i < data.length; i += 1) {
  122. if (content === '') {
  123. content = convert('prefix') + data[i] + convert('suffix');
  124. } else {
  125. content = convert('prefix', content) + data[i] + convert('suffix', content);
  126. }
  127. }
  128. } else {
  129. content = 'Error: No data found. Check your remote source!';
  130. }
  131. }
  132. // _______ Run _______
  133. function run(content, timeout) {
  134. update(both, content);
  135. two.css({[convert('start')]: one.width()})
  136. setTimeout(function() {
  137. let width = one.width();
  138. let speed = settings.speed * width;
  139. animateSlide(one, 0, -width, speed);
  140. animateSlide(two, width, 0, speed);
  141. }, timeout);
  142. }
  143. // _______ Update _______
  144. function update(slide, content) {
  145. slide.html(content);
  146. while (container.width() > slide.width()) {
  147. slide[convert('update')](convert('update', content));
  148. }
  149. slide[convert('update')]('&nbsp;');
  150. }
  151. // _______ Animation _______
  152. function animateSlide(slide, start, destination, speed) {
  153. slide.animate(
  154. {[convert('start')]: destination},
  155. speed,
  156. 'linear',
  157. function() {
  158. let width;
  159. if (start === 0) {
  160. if (slide === one && oneNeedsUpdate) {
  161. update(one, content);
  162. oneNeedsUpdate = false;
  163. } else if (slide === two && twoNeedsUpdate) {
  164. update(two, content);
  165. twoNeedsUpdate = false;
  166. }
  167. slide === one ? width = two.width() : width = one.width();
  168. speed = settings.speed * width;
  169. slide.css({[convert('start')]: width});
  170. animateSlide(slide, width, 0, speed);
  171. } else {
  172. slide === one ? width = one.width() : width = two.width();
  173. speed = settings.speed * width;
  174. animateSlide(slide, 0, -width, speed);
  175. }
  176. }
  177. );
  178. }
  179. // _______ Resize _______
  180. localWindow.on('resize', function() {
  181. let width = localWindow.width();
  182. if (width != localWindowWidth) {
  183. if (width > localWindowWidth) {
  184. if (convert('position', one)) {
  185. update(one, content);
  186. twoNeedsUpdate = true;
  187. } else if (convert('position', two)) {
  188. update(two, content);
  189. oneNeedsUpdate = true;
  190. }
  191. } else {
  192. oneNeedsUpdate = true;
  193. twoNeedsUpdate = true;
  194. }
  195. localWindowWidth = width;
  196. }
  197. });
  198. // _______ Init _______
  199. init();
  200. return this;
  201. };
  202. })(jQuery, window, document);