/* Description: Creates homepage slider (used in top of right column as of 2016/12/09). Uses json data from RC Slides and creates a slideshow with it. Dependencies: google analytics for _gaq.push click events /include/footer_includes_before_body.js?v=1 (as of 2016/12/09) Table of Contents: GET SCRIPT PARAMETERS POLYFILLS UTILITY FUNCTIONS CROSS-SCRIPT VARIABLES SCRIPT VARIABLES SCRIPT FUNCTIONS MAIN SCRIPT Change Log: 3/13/2017 - Rowland - Mobile slideshow fix */ /////////////////////////// // GET SCRIPT PARAMETERS // /////////////////////////// function get_slideshow_id() { var scripts = document.getElementsByTagName('script'); var lastScript = scripts[scripts.length-1]; var scriptName = lastScript; return scriptName.getAttribute('data-id'); } var slideshow_id = get_slideshow_id(); /////////////// // POLYFILLS // /////////////// // Polyfill for IE9 and below for third parameter on setTimeout function /*\ |*| |*| Polyfill which enables the passage of arbitrary arguments to the |*| callback functions of JavaScript timers (HTML5 standard syntax). |*| |*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval |*| |*| Syntax: |*| var timeoutID = window.setTimeout(func, delay[, param1, param2, ...]); |*| var timeoutID = window.setTimeout(code, delay); |*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]); |*| var intervalID = window.setInterval(code, delay); |*| \*/ (function() { setTimeout(function(arg1) { if (arg1 === 'test') { // feature test is passed, no need for polyfill return; } var __nativeST__ = window.setTimeout; window.setTimeout = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) { var aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? function() { vCallback.apply(null, aArgs); } : vCallback, nDelay); }; }, 0, 'test'); var interval = setInterval(function(arg1) { clearInterval(interval); if (arg1 === 'test') { // feature test is passed, no need for polyfill return; } var __nativeSI__ = window.setInterval; window.setInterval = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) { var aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? function() { vCallback.apply(null, aArgs); } : vCallback, nDelay); }; }, 0, 'test'); }()) // getElementsByClassName(search) if (!Element.prototype.getElementsByClassName) { Element.prototype.getElementsByClassName = function (search) { var d = this, elements, pattern, i, results = []; if (d.querySelectorAll) { // IE8 return d.querySelectorAll("." + search); } if (d.evaluate) { // IE6, IE7 pattern = ".//*[contains(concat(' ', @class, ' '), ' " + search + " ')]"; elements = d.evaluate(pattern, d, null, 0, null); while ((i = elements.iterateNext())) { results.push(i); } } else { elements = d.getElementsByTagName("*"); pattern = new RegExp("(^|\\s)" + search + "(\\s|$)"); for (i = 0; i < elements.length; i++) { if (pattern.test(elements[i].className)) { results.push(elements[i]); } } } return results; } } /////////////////////// // UTILITY FUNCTIONS // /////////////////////// // These help attach and remove events while supporting IE8 function addEvent(el, type, handler) { if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler); } function removeEvent(el, type, handler) { if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler); } function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } function hasClass(el, className) { return el.classList ? el.classList.contains(className) : new RegExp('\\b'+ className+'\\b').test(el.className); } function addClass(el, className) { if (el.classList) el.classList.add(className); else if (!hasClass(el, className)) el.className += ' ' + className; } function removeClass(el, className) { if (el.classList) el.classList.remove(className); else el.className = el.className.replace(new RegExp('\\b'+ className+'\\b', 'g'), ''); } function isInt(value) { return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value)) } ////////////////////// // SCRIPT VARIABLES // ////////////////////// var ss_slide_time = 5000; // 50000 if(siteName == 'politics') { var ss_slide_time = 50000; // 50000 } var ss_transition_time = 500; var ss_frame_time = 20; var ss_opacity_perc_1 = 100; var ss_opacity_perc_2 = 0; var ss_current_slide = 1; var ss_previous_slide = 1; var ss_next_slide = ss_current_slide + 1; var loading_bar_perc = 0; var loading_bar_interval; var play_or_pause = 'play'; var ss_transitioning = false; var fade_or_slide = 'slide'; var hp_slideshow_started = false; var hp_slideshow_second = false; if(slideshow_id == null || !isInt(slideshow_id) ) { slideshow_id = 15; } //////////////////////////// // CROSS-SCRIPT VARIABLES // //////////////////////////// // Shared cache busting variable available to all scripts if(typeof cache_bust === 'undefined') { var cache_bust = Math.floor(new Date().getTime() / 1000); } // Used to override slideshow src if defined if(typeof slideshow_src === 'undefined') { var slideshow_src = '/widgets/slideshow_'+slideshow_id+'.json?cache='+cache_bust; } // Used to override slideshow callback function if defined if(typeof slideshow_callback === 'undefined') { var slideshow_callback = 'hp_slideshow_callback_'+slideshow_id; } // Used to add dark transparent background if defined if(typeof slideshow_dark_back === 'undefined') { var slideshow_dark_back = false; } ////////////////////// // SCRIPT FUNCTIONS // ////////////////////// // Callback function for slideshow jsonp window[slideshow_callback] = function(data) { // Top level selector. Makes sure it's not the clone in the RCP homepage mobile duplicate var ss_selector = '.beta-container:not(.clone) .hp_ss_container'; // keep checking for existance of container at an interval of 1 sec if(document.querySelector(ss_selector+' .slides') == null) { setTimeout(window[slideshow_callback].bind(null, data), 1000); return false; } // Don't allow to be run more than once. // Could be triggered again through another widget, like recommended if(hp_slideshow_started) { return false; } hp_slideshow_started = true; // Create slides var html = ''; for(var i = 0; i < data.slides.length; i++) { var s = data.slides[i]; var img_url = s.image_url.replace('_1_', '_4_'); // Larger images var dark_back_class = ''; if(typeof slideshow_dark_back !== 'undefined' && slideshow_dark_back) { dark_back_class = 'dark_back'; } html += ''; html += '
'; html += '
'+s.title+'
'; //html += '
'+s.description+''; if(s.byline != '') { html += '
'+s.byline+'
'; } if(typeof s.subtitle_html !== 'undefined' && s.subtitle_html != '') { html += '
'+s.subtitle_html+'
'; } else if(s.subtitle != '') { html += '
'+s.subtitle+'
'; } html += '
'; html += ''; } document.querySelector(ss_selector+' .slides').innerHTML = html; // Create slide previews html = ''; for(var i = 0; i < data.slides.length; i++) { var s = data.slides[i]; var img_url = s.image_url.replace('_1_', '_4_'); // Larger images html += '
'; html += '
'; html += ''+s.title+''; html += '
'; html += '
'; html += '
'+s.title+'
'; html += '
'; html += '
'; html += '
'; } document.querySelector(ss_selector+' .slide_previews').innerHTML = html; slide_tracking(ss_selector); start_slideshow(ss_selector); } function slide_tracking(ss_selector) { var ss_container = document.querySelector(ss_selector+' .slides'); var slides = ss_container.getElementsByClassName('slide'); for(var i = 0; i < slides.length; i++) { delete slides[i].onclick; slides[i].onclick = function() { var this_slide_num = this.getAttribute('data-slide-num'); _gaq.push(['_trackEvent', 'HP_Carousel_Slider', 'Click', 'Slide: ' + this_slide_num]); }; } } function start_slideshow(ss_selector) { var ss_container = document.querySelector(ss_selector+' .slides'); var slides = ss_container.getElementsByClassName('slide'); if(slides.length <= 1) { document.querySelector(ss_selector+' .loading_bar').style.display = 'none'; document.querySelector(ss_selector+' .navigation').style.display = 'none'; return; } // Build buttons var html = ''; html += '
<
'; for(var i = 0; i < slides.length; i++) { var active_class = ''; if(i == 0) { active_class = 'active'; } html += '
'+(i+1)+'
'; } html += '
>
'; document.querySelector(ss_selector+' .navigation .buttons').innerHTML = html; // Remove loading graphic document.querySelector(ss_selector+' .slides_container').style.background = 'none'; // Hover on buttons init_button_hover(ss_selector); // Start autoplay start_slideshow_autoplay(ss_selector); // Play/Pause functionality init_play_pause(ss_selector); // Click for buttons init_button_click(ss_selector); // Click for arrows init_arrow_click(ss_selector); } function start_slideshow_autoplay(ss_selector) { if(play_or_pause == 'play') { loading_bar_interval = setInterval(loading_bar_grow, ss_frame_time, ss_selector); } } function loading_bar_grow(ss_selector) { var loading_bar = document.querySelector(ss_selector+' .loading_bar .inner_bar'); loading_bar_perc += (ss_frame_time / ss_slide_time) * 100; loading_bar.style.width = loading_bar_perc+'%'; if(loading_bar_perc >= 100) { clearInterval(loading_bar_interval); loading_bar_perc = 0; slideshow_transition(ss_selector); } } function slideshow_transition(ss_selector) { ss_transitioning = true; var slides = document.querySelectorAll(ss_selector+' .slides .slide'); // Permanently set base opacity of arrows by adding class if(!hp_slideshow_second) { addClass(document.querySelector(ss_selector+' .arrow.left'), 'active'); addClass(document.querySelector(ss_selector+' .arrow.right'), 'active'); hp_slideshow_second = true; } slides[ss_current_slide - 1].style.display = 'block'; slides[ss_next_slide - 1].style.display = 'block'; if(ss_opacity_perc_1 > 0) { var perc_amount = (ss_frame_time / ss_transition_time) * 100; ss_opacity_perc_1 -= perc_amount; ss_opacity_perc_2 += perc_amount; slides[ss_current_slide - 1].style.opacity = ss_opacity_perc_1 / 100; slides[ss_next_slide - 1].style.opacity = ss_opacity_perc_2 / 100; setTimeout(slideshow_transition, ss_frame_time, ss_selector); } else { // Restart slideshow transition for(var i = 0; i < slides.length; i++) { slides[i].style.display = 'none'; } ss_previous_slide = ss_current_slide; ss_current_slide = ss_next_slide; ss_opacity_perc_1 = 100; ss_opacity_perc_2 = 0; ss_next_slide = ss_current_slide + 1; if(ss_next_slide > slides.length) { ss_next_slide = 1; } slides[ss_current_slide - 1].style.display = 'block'; var loading_bar = document.querySelector(ss_selector+' .loading_bar .inner_bar'); //loading_bar.style.width = '0%'; // Set new active button var buttons = document.querySelectorAll(ss_selector+' .navigation .buttons .button'); removeClass(buttons[ss_previous_slide], 'active'); addClass(buttons[ss_current_slide], 'active'); init_button_hover(ss_selector); // Set position of triangle for new active location document.querySelector(ss_selector+' .navigation .active_arrow').style.left = (21+((ss_current_slide-1)*21))+'px'; ss_transitioning = false; start_slideshow_autoplay(ss_selector); } } function init_play_pause(ss_selector) { // Set play button text var play_pause = document.querySelector(ss_selector+' .navigation .play_pause'); if(play_or_pause == 'play') { play_pause.innerHTML = 'Pause ❚❚'; } else { play_pause.innerHTML = 'Play ►'; } // Init click delete play_pause.onclick; play_pause.onclick = function() { if(play_or_pause == 'play') { // Pause slideshow play_or_pause = 'pause'; play_pause.innerHTML = 'Play ►'; clearInterval(loading_bar_interval); } else { // Play slideshow play_or_pause = 'play'; play_pause.innerHTML = 'Pause ❚❚'; start_slideshow_autoplay(ss_selector); } }; } function init_arrow_click(ss_selector) { var arrow_left = document.querySelector(ss_selector+' .arrow.left'); var arrow_right = document.querySelector(ss_selector+' .arrow.right'); delete arrow_left.onclick; arrow_left.onclick = function() { var ss_container = document.querySelector(ss_selector+' .slides'); var slides = ss_container.getElementsByClassName('slide'); var slide_num = ss_current_slide - 1; if(slide_num < 1) { slide_num = slides.length; } post_click_button_arrow(ss_selector, slide_num); }; delete arrow_right.onclick; arrow_right.onclick = function() { var ss_container = document.querySelector(ss_selector+' .slides'); var slides = ss_container.getElementsByClassName('slide'); var slide_num = ss_current_slide + 1; if(slide_num > slides.length) { slide_num = 1; } post_click_button_arrow(ss_selector, slide_num); }; } function post_click_button_arrow(ss_selector, slide_num) { // Fill and stop loading bar ss_next_slide = slide_num; if(play_or_pause == 'play') { loading_bar_perc = 100; } else { slideshow_transition(ss_selector); } var slide_previews = document.querySelectorAll(ss_selector+' .slide_previews .slide_preview'); for(var i = 0; i < slide_previews.length; i++) { slide_previews[i].style.display = 'none'; } } function init_button_click(ss_selector) { var buttons = document.querySelectorAll(ss_selector+' .navigation .buttons .button'); for(var i = 0; i < buttons.length; i++) { delete buttons[i].onclick; buttons[i].onclick = function() { if( (!isNumeric(this.innerHTML) && this.innerHTML != '>' && this.innerHTML != '<') || hasClass(this, 'active')) { return false; } if(ss_transitioning) { return false; } var slide_num = 1; var ss_container = document.querySelector(ss_selector+' .slides'); var slides = ss_container.getElementsByClassName('slide'); if( isNumeric(this.innerHTML) ) { slide_num = parseInt(this.innerHTML); } else if(this.innerHTML == '>') { slide_num = ss_current_slide + 1; if(slide_num > slides.length) { slide_num = 1; } } else if(this.innerHTML == '<') { slide_num = ss_current_slide - 1; if(slide_num < 1) { slide_num = slides.length; } } post_click_button_arrow(ss_selector, slide_num); }; } } function init_button_hover(ss_selector) { var buttons = document.querySelectorAll(ss_selector+' .navigation .buttons .button'); for(var i = 0; i < buttons.length; i++) { delete buttons[i].onmouseover; buttons[i].onmouseover = function() { if(!isNumeric(this.innerHTML) || hasClass(this, 'active')) { return false; } var slide_num = parseInt(this.innerHTML) - 1; var slide_previews = document.querySelectorAll(ss_selector+' .slide_previews .slide_preview'); slide_previews[slide_num].style.display = 'block'; // Position of slide preview slide_previews[slide_num].style.left = (this.offsetLeft - 66)+'px'; }; delete buttons[i].onmouseout; buttons[i].onmouseout = function() { if( !isNumeric(this.innerHTML) ) { return false; } var slide_num = parseInt(this.innerHTML) - 1; var slide_previews = document.querySelectorAll(ss_selector+' .slide_previews .slide_preview'); slide_previews[slide_num].style.display = 'none'; }; } } ///////////////// // MAIN SCRIPT // ///////////////// var html = ''; // Styles for slideshow html += ''; // Slideshow container markup html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; html += ''; html += '
'; html += '
'; html += '
'; //document.write(html); $('.rc-hp-slides').append(html); // Get JSONP slideshow data var script = document.createElement('script'); script.src = slideshow_src; document.body.appendChild(script);