Skip To Content
CNN Max: Stay up to date with our 24/7 live news feed. Available to all Max subscribers at no additional cost. Plans start at $9.99/month.
NOW STREAMING
2024 Election Coverage
Stream the New Series, Weekdays at 7 AM ET
5 Things with Kate Bolduan brings you the five essential stories that — in five minutes or less — will get you up to speed and on with your day. Stream it live or anytime, only on CNN Max.
CNN Max Schedule
" + el.title + "
" + el.description + "
"; airingDiv.innerHTML = airingDivInner; scheduleWrapper.append(airingDiv); }); // Add LIVE badge let todayTab = document.querySelector('.date-tabs button:first-child').classList.contains('active'); if (todayTab) { // Accounting for 2 hour of caching let timeDivs = document.querySelectorAll('.schedule-list .col-time'); let currentLiveTime; const rightNowHour = new Date().getHours(); for (let i = 0; i < 2; i++) { // just look through the first two elements to add the live badge let hourText = Number(timeDivs[i].innerText.split(':')[0]); // convert to 24h time formatting if (timeDivs[i].innerText.includes('pm') && hourText < 12) { hourText = hourText + 12; } else if (timeDivs[i].innerText.includes('am') && hourText == 12) { hourText = hourText - 12; } if (rightNowHour === hourText) { // if time is exactly the same, add the live badge, break out of loop to prevent adding a second badge on the second loop addLiveBadge(timeDivs[i]); break; } else if (i > 0 && rightNowHour < hourText) { // if we're at the second item on the list and it is further in the future than the current time, we need to add the live badge to the previous element at index 0, even if the element's hourText does not equal the current hour addLiveBadge(timeDivs[0]); } } }}// // FETCH DATA//const getSchedule = async () => { // live endpoint const response = await fetch('https://d2m4gxg7423sce.cloudfront.net/Gracenote/max/linear_feed.xml'); const feedText = await response.text(); const parser = new DOMParser(); const feedDoc = parser.parseFromString(feedText, 'text/xml'); // static for testing on CMS // const parser = new DOMParser(); // const feedDoc = parser.parseFromString(window.feedText, 'text/xml'); const dateDiffInDays = (a, b) => { const _MS_PER_DAY = 1000 * 60 * 60 * 24; // Discard the time and time-zone information. const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); return Math.abs(Math.floor((utc2 - utc1) / _MS_PER_DAY)); } // initialize jagged array: length = 14 + 1, or 2 weeks plus 1 day of possible 24 hour overflow let scheduleArr = Array.from(Array(15), () => new Array()); // populate array: each date as own array with respective airings feedDoc.querySelectorAll('Airing').forEach(el => { let airing = {}; airing.title = el.querySelector('EpisodeTitle').textContent; airing.description = el.querySelector('Description').children[0].textContent; airing.duration = el.querySelector('Duration').textContent; airing.image = el.querySelector('Image[type="default"] URL').textContent; airing.startTime = new Date(el.querySelector('StartTime').textContent); const today = new Date(); const diffInDays = dateDiffInDays(airing.startTime, today); if (scheduleArr[diffInDays]) { scheduleArr[diffInDays].push(airing); } }); // sort airings within each date chronologically scheduleArr.forEach((dayArr, i) => { dayArr.sort((a, b) => { return a.startTime - b.startTime; }); // remove consecutive repetitions // overwrite respective date array with shallow copy from filter scheduleArr[i] = dayArr.filter((airing, j, arrRef) => { // keep first airing, then check for repetitions return j === 0 || airing.title !== arrRef[j - 1].title; }); }) return scheduleArr;}const scrollToCurrentTimeOnSchedule = () => {console.log('SCROLL TO CURRENT TIME ON SCHEDULE'); const scheduleContainer = document.querySelector('.schedule-list'); const scheduleList = document.querySelector('#schedule-wrapper').children; // Scroll to current time of that day for all buttons including "Today" due to caching for (let i = 0; i < scheduleList.length; i++) { const timeText = scheduleList[i].children[0].children[0].children[0].textContent; let hourText = Number(timeText.split(':')[0]); // convert to 24h time formatting if (timeText.includes('PM') && hourText < 12) { hourText = hourText + 12; } else if (timeText.includes('AM') && hourText == 12) { hourText = hourText - 12; } const rightNowHour = new Date().getHours(); if (rightNowHour === hourText) { // if time is exactly the same scheduleContainer.scrollTop = scheduleList[i].offsetTop; break; } else if (rightNowHour !== 0 && rightNowHour === (hourText - 1)) { // otherwise scroll to the previous/currently playing program scheduleContainer.scrollTop = scheduleList[i - 1].offsetTop; break; } }};document.addEventListener('DOMContentLoaded', function () { getSchedule().then(data => { return scheduleResolved = data; }).then(() => { buildDaySchedule(activeNavItemIndex); scrollToCurrentTimeOnSchedule(); }); // Scroll date tabs into view on click // Get the button elements const buttons = document.querySelectorAll('.date-tabs .row button'); // Add click event listener to each button buttons.forEach(function (button) { button.addEventListener('click', function () { // Calculate the center position of the parent div const parentDiv = document.querySelector('.date-tabs .row'); const centerPosition = (button.offsetLeft + button.offsetWidth / 2) - parentDiv.offsetWidth / 2; // Scroll to the calculated center position parentDiv.scrollTo({ left: centerPosition, behavior: 'smooth' }); scrollToCurrentTimeOnSchedule(); }); }); // Get the button elements const buttonTabs = document.querySelectorAll('.date-tabs .row button'); // Add click event listener to each button buttonTabs.forEach(function (button) { // Add keydown event listener for Enter key button.addEventListener('keydown', function (event) { if (event.key === 'Enter') { // Trigger the click event if Enter key is pressed button.click(); } }); });});