Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Автоматический отсчёт до времени окончания акции с плагином TimeTo (https://javascript.ru/forum/jquery/57256-avtomaticheskijj-otschjot-do-vremeni-okonchaniya-akcii-s-plaginom-timeto.html)

Sigizmund2012 27.07.2015 12:52

Автоматический отсчёт до времени окончания акции с плагином TimeTo
 
Здравствуйте. На сайте каждую неделю в пятницу в час ночи стартует шабаш ведьм новая акция, а старая соответственно заканчивается. Установлен таймер обратного отсчёта timeTo, дата каждую пятницу вводилась вручную. Я это дело автоматизировал, но наворотил такого, что самому страшно:
var today = new Date();
var currentDay = today.getDay();
var timeToEndAction;

switch (currentDay){
	case 0: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 5)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 1: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 4)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 2: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 3)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 3: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 2)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 4: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 1)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 5: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 7)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;
	case 6: timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate() + 6)).setHours(1)).setMinutes(0)).setSeconds(0);
		break;

}

$('#countdown').timeTo( {
	timeTo: new Date(timeToEndAction),
	displayDays: 2
	} );

Вопрос: можно ли как-то код улучшить(упростить) особенно switch?

ksa 27.07.2015 16:36

Цитата:

Сообщение от Sigizmund2012
особенно switch?

Например заменить его на элементарный массив

var a=[5,4,3,2,1,7,6];
timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate()+a[currentDay])).setHours(1)).setMinutes(0)).setSeconds(0);

Sigizmund2012 27.07.2015 17:20

Цитата:

Сообщение от ksa
Например заменить его на элементарный массив

Отличная идея, чуть хуже читаемость(как по мне), но код изрядно сокращает.

рони 27.07.2015 17:31

таймер время до часу пятницы
 
Sigizmund2012,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script src="http://lexxus.github.io/jq-timeTo/js/jquery.timeTo.min.js"></script>
  <link rel="stylesheet" type="text/css" media="screen" href="http://lexxus.github.io/jq-timeTo/stylesheets/stylesheet.css">

    <link rel="stylesheet" type="text/css" media="screen" href="http://lexxus.github.io/jq-timeTo/stylesheets/timeTo.css">
    <style type="text/css">
    #countdown{
      margin: 70px;
    }

  </style>
  <script>
    $(function() {
    var b = [5, 4, 3, 2, 1, 7, 6],
        a = new Date,
        d = a.getHours(),
        c = a.getDay(),
        b = new Date(a.getFullYear(), a.getMonth(), a.getDate() + (5 != c || d ? b[c] : 0), 1, 0, 0);
    $("#countdown").timeTo({
        timeTo: b,
        displayDays: 2,
        theme: "white",
        displayCaptions: !0,
        fontSize: 48,
        captionSize: 14,
        lang: "ru"
    })
});
  </script>
</head>

<body>
<div id="countdown"></div>


</body>

</html>

рони 27.07.2015 18:02

Sigizmund2012,
выше код правильный но бесполезный
правильный код
$('#clock').timeTo({
seconds: количество секунд до даты согласно серверу а не времени на клиенте});

Sigizmund2012 27.07.2015 18:18

рони,
Как обычно коротко, но можно голову сломать пока поймёшь, как работает. Кстати, в коде (5 != c || d ? b[c] : 0) непонятно, зачем часы с 5 сравнивать, нужно ведь учитывать время в пятницу от 0 до 1 ночи. Все эти a,b,c трудно читаются. Доработал свой говнокод, получилось так:
var today = new Date();
var currentDay = today.getDay();
var currentHours = today.getHours();
var timeToEndAction;

var arr=[5,4,3,2,1,7,6];
timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate()+( (currentDay === 5 && currentHours < 1 ) ? 0 : arr[currentDay] ))).setHours(1)).setMinutes(0)).setSeconds(0);

$('#countdown').timeTo( {
	timeTo: new Date(timeToEndAction),
	displayDays: 2
	} );

Sigizmund2012 27.07.2015 18:49

Цитата:

Сообщение от рони
количество секунд до даты согласно серверу а не времени на клиенте

Верно, пришлось с сервера время брать. Вот что получилось:
jQuery(document ).ready(function(){
	var today;
	var currentDay;
	var currentHours;
	var timeToEndAction;
	var arr=[5,4,3,2,1,7,6];
	$.ajax({
		url: "/sendmailforms/time.php",
		cache: false,
		success: function(data){
			today = new Date(data);
			currentDay = today.getDay();
			currentHours = today.getHours();
			timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate()+( (currentDay === 5 && currentHours < 1 ) ? 0 : arr[currentDay] ))).setHours(1)).setMinutes(0)).setSeconds(0);
			$('#countdown').timeTo( {
				timeTo: new Date(timeToEndAction),
				displayDays: 2
			} );
		}
	});
});

рони 27.07.2015 19:02

Sigizmund2012,
currentDay === 5 && currentHours < 1 === currentDay === 5 && !currentHours === 5 != c || d

5 != c || d перевод сегодня не пятница или время больше 1 часа

рони 27.07.2015 19:19

Sigizmund2012,
вопрос остался зачем все строки кроме
Цитата:

Сообщение от рони
$('#clock').timeTo({
seconds: количество секунд до даты согласно серверу а не времени на клиенте});

нафига ajax и прочая лабуда?

Sigizmund2012 27.07.2015 19:25

Цитата:

Сообщение от рони (Сообщение 381749)
Sigizmund2012,
currentDay === 5 && currentHours < 1 === currentDay === 5 && !currentHours === 5 != c || d

5 != c || d перевод сегодня не пятница или время больше 1 часа

Вообще нихрена не понял. Похоже я путаюсь в приоритете операторов, выражение 5 != c || d ? b[c] : 0 нужно вот так читать что-ли?: (5 != c) || (d ? b[c] : 0). Но оно же в результате вернёт булев тип.

Sigizmund2012 27.07.2015 19:40

Цитата:

Сообщение от рони
нафига ajax и прочая лабуда?

Через ajax я получаю текущую дату и обрабатываю её на клиенте. PHP не знаю, поэтому рассчитать количество секунд не могу, но даже если б мог, всё равно ajax нужен для запроса к серверу. Или вы что-то типа $.get() имели ввиду? Это ж всё равно ajax, просто синхронный.

рони 27.07.2015 20:06

Sigizmund2012,
ненужен запрос совсем достаточно распечатать число при первоначальной отдаче страницы - сам не знаю php

что то типа
$('#countdown').timeTo({
seconds: echo (date("s") - date("s")) ,
displayDays: 2

})

рони 27.07.2015 20:26

Sigizmund2012, для медитации
PHP. Сколько дней/часов/минут/секунд осталось до указанного события.

Deff 28.07.2015 04:45

По опыту, наилучшее, отдавать сервером скрипт-переменную: Гринвич-время(в секундах) отдачи страницы севером.
Тады простенький таймер на странице позволяет отсчитывать всякие фичи до нужных событий.
Для полного кайфа отдают переменной и тайм зону текущего юзера(типично она настраивается юзером в профиле)

Sigizmund2012 28.07.2015 09:06

Цитата:

Сообщение от рони
ненужен запрос совсем достаточно распечатать число при первоначальной отдаче страницы

Я изначально так и сделал, но в консоль ошибка дропнулась, что скобки не хватает у аргумента new Date, я решил что это с php проблема какая-то и сделал через ajax. Оказалось просто блок php надо в кавычки закрыть, окончательный код такой:
var today = new Date( '<?php echo date("c"); ?>' );
	var currentDay = today.getDay();
	var currentHours = today.getHours();
	var timeToEndAction;
	var arr = [5,4,3,2,1,7,6];
	timeToEndAction = new Date(new Date(new Date(new Date().setDate(today.getDate()+( (currentDay === 5 && currentHours < 1 ) ? 0 : arr[currentDay] ))).setHours(1)).setMinutes(0)).setSeconds(0);
	$('#countdown').timeTo( {
		timeTo: new Date(timeToEndAction),
		displayDays: 2
	} );

рони 28.07.2015 10:37

Цитата:

Сообщение от Deff
Тады простенький таймер на странице позволяет отсчитывать всякие фичи до нужных событий.

нафига если сервер может сделать этоже самое при отдаче страницы - но дело ваше раз хотите на клиенте вычислять

Deff 28.07.2015 10:55

рони,
У сервера отдача плюс/минус полминуты, если тьву нужно запускать ровно в 9:00, (К примеру так у меня лотерейка запускается на пять мин)
То проще от получения странице сходу вычислить нужную поправку и запустить свой более точный таймер в нужное время от текущего, а серв еще может страницу и не отдать, а так работаем с чем есть

рони 28.07.2015 11:28

:( :( :( надо то всего php программисту глянуть, всё ли верно
<script>
    $(function() {
       $("#countdown").timeTo({
    seconds: <?php
    ini_set('display_errors', 'Off');
    $a = strtotime("now");
    $b = strtotime("next Friday 1 hours 0 seconds");
    echo ($b - $a);

?>,
        displayDays: 2,
        theme: "white",
        displayCaptions: !0,
        fontSize: 48,
        captionSize: 14,
        lang: "ru"
    })
});
  </script>

Sigizmund2012 31.07.2015 11:28

Цитата:

Сообщение от рони (Сообщение 381878)
:( :( :( надо то всего php программисту глянуть, всё ли верно
<script>
    $(function() {
       $("#countdown").timeTo({
    seconds: <?php
    ini_set('display_errors', 'Off');
    $a = strtotime("now");
    $b = strtotime("next Friday 1 hours 0 seconds");
    echo ($b - $a);

?>,
        displayDays: 2,
        theme: "white",
        displayCaptions: !0,
        fontSize: 48,
        captionSize: 14,
        lang: "ru"
    })
});
  </script>

Ага, этот плагин берёт начало отсчёта на клиенте, если дата окончания задана через timeTo. Я немного по-другому сделал:
<?php

/* Count seconds before action ending */
$currentDay = date( "w" );
$arrDays = array("5", "4", "3", "2", "1", "7", "6");
$secondsToEndAction = mktime(1, 0, 0, date("n"), date("j") + $arrDays[$currentDay], date("Y")) - time();

?>

$('#countdown').timeTo( {
		seconds: <?php echo $secondsToEndAction ?>,
		displayDays: 2
	} );


Часовой пояс GMT +3, время: 05:56.