Страницы

Поиск по вопросам

среда, 10 октября 2018 г.

Как правильно внести изменения в скрипт таймера обратного отсчета времени

Всех приветствую! Прошу помощи. Есть скрипт таймера обратного отсчета времени до определенной даты. Помогите, пожалуйста, внести в него изменения. Есть несколько моментов:
Необходимо добавить в скрипт таймера количество месяцев и количество лет. Второй момент, не могу разобраться, когда таймер заканчивает отсчет, блок становится пустым. Как сделать так, чтобы по окончании таймера, в этом блоке появлялся другой блок? И еще один момент: скрипт ориентирован не на нашего брата, АМ и РМ, не совсем это удобно, возможно ли это изменить, а также поменять местами в первой строке скрипта число и месяц? Очень буду благодарен всем за любую помощь!
скрипт:
var end = new Date('12/01/2018 12:00 AM');
var _second = 1000; var _minute = _second * 60; var _hour = _minute * 60; var _day = _hour * 24; var timer;
function showRemaining() { var now = new Date(); var distance = end - now; if (distance < 0) { clearInterval(timer); return; } var days = Math.floor(distance / _day); var hours = Math.floor((distance % _day) / _hour); var minutes = Math.floor((distance % _hour) / _minute); var seconds = Math.floor((distance % _minute) / _second);
var daysLabel = pluralize(days, 'Дней'); var hoursLabel = pluralize(hours, 'Часов'); var minutesLabel = pluralize(minutes, 'Минут'); var secondsLabel = pluralize(seconds, 'Секунд');
var days = leadingZero(days); var hours = leadingZero(hours); var minutes = leadingZero(minutes); var seconds = leadingZero(seconds);
function pluralize(number, text) { if(number === 1) { return text; } else { return text+'' } }
function leadingZero(number) { if(number < 10) { return '0'+number; } else { return number; } }
$('.chart__bar--days .chart__bar-number').html(days); $('.chart__bar--days').css('height', ((days/360)*100)+'%'); $('.chart__bar--days .chart__bar-label').html(daysLabel);
$('.chart__bar--hours .chart__bar-number').html(hours); $('.chart__bar--hours').css('height', ((hours/24)*100)+'%'); $('.chart__bar--hours .chart__bar-label').html(hoursLabel);
$('.chart__bar--minutes .chart__bar-number').html(minutes); $('.chart__bar--minutes').css('height', ((minutes/60)*100)+'%'); $('.chart__bar--minutes .chart__bar-label').html(minutesLabel);
$('.chart__bar--seconds .chart__bar-number').html(seconds); $('.chart__bar--seconds').css('height', ((seconds/60)*100)+'%'); $('.chart__bar--seconds .chart__bar-label').html(secondsLabel); }
timer = setInterval(showRemaining, 1000);
html:


css:
.widget { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; } .widget__foreground { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; } .widget--countdown__main { position: absolute; width: 50%; left: 50px; top: 120px; font-family: PT Serif Caption,Georgia,Times New Roman,Times,serif; color: #000000; text-shadow: #fff 1px 0px, #fff 1px 1px, #fff 0px 1px, #fff -1px 1px, #fff -1px 0px, #fff -1px -1px, #fff 0px -1px, #fff 1px -1px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px; } .widget--countdown__title { font-size: 36px; line-height: 42px; font-weight: 700; margin: 0 50px 20px 0; } .widget--countdown__supporting-text { margin-bottom: 25px; line-height: 17px; width: 50%; } .widget--countdown__chart { height: 100%; width: 50%; max-width: 470px; position: absolute; right: 50px; } .chart { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; display: flex; justify-content: space-between; } .chart__bar { width: 23%; position: relative; display: inline-block; align-self: flex-end; -webkit-transition: all linear .2s; -moz-transition: all linear .2s; -ms-transition: all linear .2s; -o-transition: all linear .2s; transition: all linear .2s; } .chart__bar-content { position: absolute; bottom: 20px; width: 100%; text-align: center; } .chart__bar-number { font-size: 36px; font-weight: 300; } .chart__bar-label { text-transform: uppercase; } .chart__bar--days { background-color: rgba(0, 191, 228, .90); box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--hours { background-color: rgba(249, 108, 207, .90); box-shadow: 0px 0px 40px -5px rgba(249, 108, 207, .90); } .chart__bar--minutes { background-color: rgba(0, 207, 167, .90); box-shadow: 0px 0px 40px -5px rgba(0, 207, 167, .90); } .chart__bar--seconds { background-color: rgba(238, 138, 56, .90); box-shadow: 0px 0px 40px -5px rgba(238, 138, 56, .90); } .chart__bar--days,.chart__bar--hours,.chart__bar--minutes,.chart__bar--seconds { background-image: url(pattern-timer.png); background-position: bottom right; background-repeat: repeat; }


Ответ

upd.2 обновил ф-ю calendiff, чтобы правильно считала случаи, когда надо «отмотать» назад не один, а два месяца, для компенсации смещения в днях. Напр. чтобы компенсировать -31 день, добавить дни предыдущего одного месяца (30 дней) не достаточно, нужно заехать в пред-предыдущий месяц.
upd. Как выяснилось, надо всё-таки считать точную «календарную» дистанцию между двух дат: и от 28 января до 28 февраля (31 день), и от 28 февраля до 28 марта (28 дней) – в обоих случаях ровно 1 месяц. Поэтому написал функцию для такого «человеческого» подсчёта разницы между двумя датами.
Поскольку разметка повторяется, отличается лишь названием класса, вынес её генерацию в функцию. jQuery элементы достаточно найти один раз, и затем обращаться к сохранённым, вместо того, чтобы при каждом вызове заново искать в DOM-дереве. Добавил функцию для склонения существительных, в зависимости от числа (День, Дня, Дней). В стили добавил цвета для колонок года и месяца.
// допустимые форматы времени: // https://tools.ietf.org/html/rfc2822#page-14 // https://www.w3.org/TR/NOTE-datetime // Напр. 1 декабря 2018, полдень по Москве: var end = new Date('2018-12-01T12:00+03:00') ,offset = (new Date().getTimezoneOffset())*6E4 ,timer ,$el ,key ,html = '' ; // generate markup html = ['years','months','days','hours','minutes','seconds'] .reduce( function(p,c){ return p += makeHtml(c);}, ''); $('.widget--countdown__chart > .chart').html(html); $el = { // найти один раз и запомнить Y: { n: $('.chart__bar--years .chart__bar-number'), l: $('.chart__bar--years .chart__bar-label'), b: $('.chart__bar--years') } ,M: { n: $('.chart__bar--months .chart__bar-number'), l: $('.chart__bar--months .chart__bar-label'), b: $('.chart__bar--months') } ,D: { n: $('.chart__bar--days .chart__bar-number'), l: $('.chart__bar--days .chart__bar-label'), b: $('.chart__bar--days') } ,h: { n: $('.chart__bar--hours .chart__bar-number'), l: $('.chart__bar--hours .chart__bar-label'), b: $('.chart__bar--hours') } ,m: { n: $('.chart__bar--minutes .chart__bar-number'), l: $('.chart__bar--minutes .chart__bar-label'), b: $('.chart__bar--minutes') } ,s: { n: $('.chart__bar--seconds .chart__bar-number'), l: $('.chart__bar--seconds .chart__bar-label'), b: $('.chart__bar--seconds') } } /** * генерирует html одного блока */ function makeHtml(key) { return [ '

', '
', '
', '
', '
', '
', ].join("
").replace(/%KEY%/g, key); } function showRemaining() { var start = new Date(), r; if( end - start < 0) return timeHasCome(); r = calendiff( start, end); render( 'Y', r.years, ['Год','Года','Лет'], 3); // сколько максимум лет может быть? render( 'M', r.months, ['Месяц','Месяца','Месяцев'], 12); render( 'D', r.days, ['День','Дня','Дней'], 31); render( 'h', r.hours, ['Час','Часа','Часов'], 24); render( 'm', r.minutes, ['Минута','Минуты','Минут'], 60); render( 's', r.seconds, ['Секунда','Секунды','Секунд'], 60); } /** * Когда отсчёт закончился, или время уже прошло */ function timeHasCome() { if(timer) { window.clearInterval( timer); timer = undefined; } $('.widget.widget--countdown').html('
Баста, карапузики!
'); } function render( key, n, s, max) { $el[key].n.text( ('0' + n).slice(-2)); $el[key].l.text( getNumEnding(n, s)); $el[key].b.css('height', ((n / max) * 100) + '%'); } /** * Calendar difference between two dates * @param Date object dateIn start date * @param Date object dateOut end date * @return object with int properties * "years", "months", "days", "hours", "minutes" and "seconds" * * https://github.com/sergiks/calendiff.js * * @author Sergei Sokolov */ function calendiff( dateIn, dateOut) { var out = { years : 0 ,months : 0 ,days : 0 ,hours : 0 ,minutes : 0 ,seconds : 0 } ,sign = 1 ,diff = 0 ,proto ,monthsShift ,prop ; // check input proto = Object.prototype.toString.call(dateIn); if( proto !== '[object Date]') { dateIn = new Date( dateIn); if( isNaN( dateIn.getTime())) throw 'Incorrect "In" date format'; } proto = Object.prototype.toString.call(dateOut); if( proto !== '[object Date]') { dateOut = new Date( dateOut); if( isNaN( dateOut.getTime())) throw 'Incorrect "Out" date format'; } // check numeric difference diff = dateOut.getTime() - dateIn.getTime(); if( diff === 0) { return out; } else if( diff < 0) { sign = -1; dateOut = [dateIn, dateIn = dateOut][0]; // swap the dates } // calculate human-readable difference out.seconds += dateOut.getSeconds() - dateIn.getSeconds(); if( out.seconds < 0) { out.seconds += 60; out.minutes--; } out.minutes += dateOut.getMinutes() - dateIn.getMinutes(); if( out.minutes < 0) { out.minutes += 60; out.hours--; } out.hours += dateOut.getHours() - dateIn.getHours(); if( out.hours < 0) { out.hours += 24; out.days--; } // complex part: a month can have various number of days // when entering with a negative number of days, up to -31, // it might take up to two months shift back // should the preceding month only have 28, 29 or 30 days. out.days += dateOut.getDate() - dateIn.getDate(); while( out.days < 0) { monthsShift = 0; out.days += new Date( dateOut.getFullYear(), dateOut.getMonth() - monthsShift, 0).getDate(); monthsShift++; out.months--; } out.months += dateOut.getMonth() - dateIn.getMonth(); if( out.months < 0) { out.months += 12; out.years--; } out.years += dateOut.getFullYear() - dateIn.getFullYear(); // negative difference case if( sign < 0) for( prop in out) if( out[prop]) out[prop] *= -1; // avoid -0 values return out; } /** * Функция возвращает окончание для множественного числа слова на основании числа и массива окончаний * param iNumber Integer Число на основе которого нужно сформировать окончание * param aEndings Array Массив слов или окончаний для чисел (1, 4, 5), * например ['яблоко', 'яблока', 'яблок'] * return String */ function getNumEnding(iNumber, aEndings) { var sEnding, i; iNumber = iNumber % 100; if (iNumber>=11 && iNumber<=19) { sEnding=aEndings[2]; } else { i = iNumber % 10; switch (i) { case (1): sEnding = aEndings[0]; break; case (2): case (3): case (4): sEnding = aEndings[1]; break; default: sEnding = aEndings[2]; } } return sEnding; } timer = setInterval(showRemaining, 200); .widget { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; } .widget__foreground { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; } .widget--countdown__main { position: absolute; width: 50%; left: 50px; top: 120px; font-family: PT Serif Caption,Georgia,Times New Roman,Times,serif; color: #000000; text-shadow: #fff 1px 0px, #fff 1px 1px, #fff 0px 1px, #fff -1px 1px, #fff -1px 0px, #fff -1px -1px, #fff 0px -1px, #fff 1px -1px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px; } .widget--countdown__title { font-size: 36px; line-height: 42px; font-weight: 700; margin: 0 50px 20px 0; } .widget--countdown__supporting-text { margin-bottom: 25px; line-height: 17px; width: 50%; } .widget--countdown__chart { height: 100%; width: 50%; max-width: 470px; position: absolute; right: 50px; } .chart { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; display: flex; justify-content: space-between; } .chart__bar { width: 23%; position: relative; display: inline-block; align-self: flex-end; -webkit-transition: all linear .2s; -moz-transition: all linear .2s; -ms-transition: all linear .2s; -o-transition: all linear .2s; transition: all linear .2s; } .chart__bar-content { position: absolute; bottom: 20px; width: 100%; text-align: center; } .chart__bar-number { font-size: 36px; font-weight: 300; } .chart__bar-label { text-transform: uppercase; } .chart__bar--years { background-color: rgba(228, 191, 0, .90); box-shadow: 0px 0px 40px -5px rgba(228, 191, 0, .90); } .chart__bar--months { background-color: rgba(207, 108, 249, .90); box-shadow: 0px 0px 40px -5px rgba(207, 108, 249, .90); } .chart__bar--days { background-color: rgba(0, 191, 228, .90); box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--hours { background-color: rgba(249, 108, 207, .90); box-shadow: 0px 0px 40px -5px rgba(249, 108, 207, .90); } .chart__bar--minutes { background-color: rgba(0, 207, 167, .90); box-shadow: 0px 0px 40px -5px rgba(0, 207, 167, .90); } .chart__bar--seconds { background-color: rgba(238, 138, 56, .90); box-shadow: 0px 0px 40px -5px rgba(238, 138, 56, .90); } .chart__bar--days,.chart__bar--hours,.chart__bar--minutes,.chart__bar--seconds { background-image: url(pattern-timer.png); background-position: bottom right; background-repeat: repeat; }

Комментариев нет:

Отправить комментарий