/*! * eocjsNewsticker v0.6.1 * Copyright (c) 2022 Dieter Schmitt * Released under the MIT license - https://opensource.org/licenses/MIT */ (function($, window, document, undefined) { $.fn.eocjsNewsticker = function(options) { // _______ Options _______ let defaults = { speed: 20, timeout: 1, divider: '+++', type: 'static', // static or ajax source: '', // ajax source (url) dataType: 'json', // data type of the expected file (json or jsonp) callback: 'callback', // used for jsonp fetch: false, // use fetch instead of $.ajax() interval: 120, // polling interval of the ajax source (seconds) direction: 'ltr' // direction (ltr or rtl) }; let settings = $.extend({}, defaults, options); // _______ Inner Variables _______ let self = this; let content = self.html(); let active = 'eocjs-newsticker-active'; let container = {}; let one = {}; let two = {}; let both = {}; let oneNeedsUpdate = false; let twoNeedsUpdate = false; let localWindow = $(window); let localWindowWidth = localWindow.width(); // _______ Init _______ function init() { if (!self.hasClass(active)) { create(); start(); self.addClass(active); } } // _______ Create _______ function create() { self.addClass('eocjs-newsticker').html('
'); container = self.find('.eocjs-newsticker-container'); one = self.find('.eocjs-newsticker-one'); two = self.find('.eocjs-newsticker-two'); both = self.find('.eocjs-newsticker-one, .eocjs-newsticker-two'); both.css({[convert('start')]: 0, [convert('end')]: 'auto'}) } // _______ Start _______ function start() { if (settings.type === 'static') { content = convert('prefix') + content + convert('suffix'); run(content, (settings.timeout * 1000)); } else if (settings.type === 'ajax') { container.prepend('
'); $.when(ajax(settings.source, settings.dataType, settings.callback, settings.fetch)).done(function(data) { setContent(data); container.find('.eocjs-newsticker-loader').fadeOut(300, function() { run(content, 0); $(this).remove(); }); setInterval(function() { $.when(ajax(settings.source, settings.dataType, settings.callback, settings.fetch)).done(function(data) { setContent(data); oneNeedsUpdate = true; twoNeedsUpdate = true; }); }, settings.interval * 1000); }); } } // _______ Additional function for LTR/RTL conversion _______ function convert(type, data) { let addition = ''; let dir = settings.direction; if (type === 'prefix') { data === undefined ? (dir !== 'rtl' ? addition = '' : addition = settings.divider + ' ') : (dir !== 'rtl' ? addition = data + ' ' : addition = settings.divider + ' '); } else if (type === 'suffix') { data === undefined ? (dir !== 'rtl' ? addition = ' ' + settings.divider : addition = '') : (dir !== 'rtl' ? addition = ' ' + settings.divider : addition = ' ' + data); } else if (type === 'start') { dir !== 'rtl' ? addition = 'left' : addition = 'right'; } else if (type === 'end') { dir !== 'rtl' ? addition = 'right' : addition = 'left'; } else if (type === 'update') { data === undefined ? (dir !== 'rtl' ? addition = 'append' : addition = 'prepend') : (dir !== 'rtl' ? addition = ' ' + data : addition = data + ' '); } else if (type === 'position') { addition = (dir !== 'rtl' && data.position().left > 0) || (dir === 'rtl' && (container.width() - (data.position().left + data.width())) > 0); } return addition; } // _______ Ajax _______ function ajax(source, dataType, callback, useFetch) { if (dataType === 'json' && useFetch) { return fetch(source).then(function(response) { return response.json(); }); } else { return $.ajax({ url: source, dataType: dataType, jsonpCallback: callback }); } } // _______ setContent _______ function setContent(data) { content = ''; if ($.isPlainObject(data) && !$.isEmptyObject(data)) { for (let property in data) { if (data.hasOwnProperty(property)) { if (content === '') { content = convert('prefix') + data[property] + convert('suffix'); } else { content = convert('prefix', content) + data[property] + convert('suffix', content); } } } } else if (Array.isArray(data) && data.length > 0) { for (let i = 0; i < data.length; i += 1) { if (content === '') { content = convert('prefix') + data[i] + convert('suffix'); } else { content = convert('prefix', content) + data[i] + convert('suffix', content); } } } else { content = 'Error: No data found. Check your remote source!'; } } // _______ Run _______ function run(content, timeout) { update(both, content); two.css({[convert('start')]: one.width()}) setTimeout(function() { let width = one.width(); let speed = settings.speed * width; animateSlide(one, 0, -width, speed); animateSlide(two, width, 0, speed); }, timeout); } // _______ Update _______ function update(slide, content) { slide.html(content); while (container.width() > slide.width()) { slide[convert('update')](convert('update', content)); } slide[convert('update')](' '); } // _______ Animation _______ function animateSlide(slide, start, destination, speed) { slide.animate( {[convert('start')]: destination}, speed, 'linear', function() { let width; if (start === 0) { if (slide === one && oneNeedsUpdate) { update(one, content); oneNeedsUpdate = false; } else if (slide === two && twoNeedsUpdate) { update(two, content); twoNeedsUpdate = false; } slide === one ? width = two.width() : width = one.width(); speed = settings.speed * width; slide.css({[convert('start')]: width}); animateSlide(slide, width, 0, speed); } else { slide === one ? width = one.width() : width = two.width(); speed = settings.speed * width; animateSlide(slide, 0, -width, speed); } } ); } // _______ Resize _______ localWindow.on('resize', function() { let width = localWindow.width(); if (width != localWindowWidth) { if (width > localWindowWidth) { if (convert('position', one)) { update(one, content); twoNeedsUpdate = true; } else if (convert('position', two)) { update(two, content); oneNeedsUpdate = true; } } else { oneNeedsUpdate = true; twoNeedsUpdate = true; } localWindowWidth = width; } }); // _______ Init _______ init(); return this; }; })(jQuery, window, document);