Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Таймер до требуемой даты в цикле (https://javascript.ru/forum/events/45883-tajjmer-do-trebuemojj-daty-v-cikle.html)

Drugpunker 19.03.2014 15:50

Таймер до требуемой даты в цикле
 
Всем здравствуйте.
Обращаюсь к знатокам JS.
Бьюсь над проблемой уже двое суток, и с каждой секундой всё больше ненавижу себя за незнание яваскрипт.

Стоит задача:
  • В цикле PHP выдать таблицы с событиями, которые произойдут в конкретные Дату и Время.
  • Соответственно, напротив каждого события должен висеть таймер обратного отсчёта

Моя реализация:
  1. Кусок кода PHP(в цикле):
    выбираю данные из базы и применяю к ним функцию countdown()
$unix_date = strtotime($date_from_db);
$unix_time = strtotime($time_from_db);
		$day = date ('d', $unix_date);
		$month = date ('n', $unix_date);
		$year = date('Y', $unix_date);
		$hour = date ('H', $unix_time);
		$minute = date ('i', $unix_time);
		$second = date ('s', $unix_time);
echo "
<td>
<span id='auct_timer'>
		
</span>
		
<script language='javascript'>
countdown(".$year.",".$month.",".$day.",".$hour.",".$minute.",".$second.")
</script>
</td>
";

  1. Собственно, функция на JS:

function countdown(yr,m,d,h,mn,s)
{
  var montharray=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
  theyear = yr;
  themonth  = m;
  theday = d;
  thehour = h;
  theminute = mn;
  thesecond = s;

  var today = new Date()
  var todayy = today.getYear()
  if (todayy < 1000) todayy += 1900
  var todaym = today.getMonth()
  var todayd = today.getDate()
  var todayh = today.getHours()
  var todaymin = today.getMinutes()
  var todaysec = today.getSeconds()
  var todaystring = montharray[todaym]+" "+todayd+" "+todayy+" "+todayh+":"+todaymin+":"+todaysec
  
  futurestring = montharray[m-1]+" "+d+", "+yr+", "+h+", "+mn+", "+s
  
  dd = Date.parse(futurestring)-Date.parse(todaystring)
  dday = Math.floor(dd/(60*60*1000*24)*1)
  dhour = Math.floor((dd%(60*60*1000*24))/(60*60*1000)*1)
  dmin = Math.floor(((dd%(60*60*1000*24))%(60*60*1000))/(60*1000)*1)
  dsec = Math.floor((((dd%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1)
  var tdays=" д. "
  var thours=" ч. "
  var tmin=" м. "
  var tsec=" c. "

if (dd == 0||dd < 0)
  {
    document.getElementByID('auct_timer').innerHTML = "Поехали!"
    return
  }
  else 
  {
    document.getElementById("auct_timer").innerHTML = futurestring//dday+tdays+dhour+thours+dmin+tmin+dsec+tsec
    setTimeout("countdown(theyear,themonth,theday,thehour,theminute,thesecond)",1000)
  }
}


  • Проблема состоит в том, что переданные данные из PHP, попадая в функцию JS изменяются непонятно (мне) как. Т.е., например, если передаю
    дату 20 апреля 2014 12:00:00 она сразу же превращается
    в May 18, 2014, 14, 12, 0. Чушь какая то?!:-/ (Вывод специально проверял; сам таймер закомментировал пока)
    Как тут вырулить, подскажите, кто знает. Или может пример похожий (именно похожий) где встречали?

  • Вторая проблема, при выводе в цикле PHP, данные ,т. е. таймер (после обработки функцией) почему то выводится только в первой таблице...? В последующих нет. Как быть тут?
Очень надеюсь на дельный совет...


Свою ситуацию брал из Здесь.

nice_try 19.03.2014 16:12

я бы сделал по другому - на php сформировал unix_time и уже его передавал в js, а тут наверчено чрезмерно

Drugpunker 19.03.2014 16:21

  • Имеется ввиду перевести дату+время (взятые из БД) в метку времени unix
  • Функцию JS применить к единственной переданной переменной
Если так, то - пытался уже. Не смог связать...

nice_try 19.03.2014 16:40

да, например, http://www.php.net/manual/en/function.mktime.php

Drugpunker 19.03.2014 16:43

Цитата:

Сообщение от nice_try (Сообщение 303237)

Эта функция не помогает

nice_try 19.03.2014 16:51

Цитата:

Сообщение от Drugpunker (Сообщение 303238)
Эта функция не помогает

в умелых руках эта функция страшное оружие :D

Drugpunker 19.03.2014 16:53

Может я не правильно её применял?

Каков принцип её применения в моей ситуации?

Erolast 19.03.2014 17:09

$unix_date = strtotime($date_from_db);
$unix_time = strtotime($time_from_db);
        $day = date ('d', $unix_date);
        $month = date ('n', $unix_date);
        $year = date('Y', $unix_date);
        $hour = date ('H', $unix_time);
        $minute = date ('i', $unix_time);
        $second = date ('s', $unix_time);
echo "
<td>
<span id='auct_timer'>
         
</span>
         
<script language='javascript'>
countdown(".$year.",".$month.",".$day.",".$hour.",".$minute.",".$second.")
</script>
</td>
";

Код же кривой - кавычки одинакового типа друг в друга вкладываешь.

nice_try 19.03.2014 17:15

Цитата:

Сообщение от Drugpunker (Сообщение 303248)
Может я не правильно её применял?

Каков принцип её применения в моей ситуации?

с помощью нее ты сможешь получить unix time в своей php функции и передать значение в js

Drugpunker 19.03.2014 17:21

Цитата:

Сообщение от nice_try (Сообщение 303255)
с помощью нее ты сможешь получить unix time в своей php функции и передать значение в js

Это мне понятно. Непонятно как мне её использовать.
Пробовал вчера - ничего не выходит.

Ввожу, к примеру 20 апреля 2014 12:13:47.
На выходе должно быть что то вроде 56556415543534561.

И этим мне нужно оперировать так?
Как вытащить данные потом? не знаю. Не получилось...

Erolast 19.03.2014 17:26

Цитата:

И этим мне нужно оперировать так?
http://javascript.ru/Date
Цитата:

Аргументы

dateVal
  • Если параметр является числовым, то он интерпретируется как количество миллисекунд от 1-Янв-1970 00:00.
  • Если строкой, то она разбирается и интерпретируется как дата по стандартным правилам Date.parse.

Методы объекта date в статье по ссылке выше подробно перечислены.

Drugpunker 19.03.2014 17:31

Цитата:

Сообщение от Erolast (Сообщение 303254)
$unix_date = strtotime($date_from_db);
$unix_time = strtotime($time_from_db);
        $day = date ('d', $unix_date);
        $month = date ('n', $unix_date);
        $year = date('Y', $unix_date);
        $hour = date ('H', $unix_time);
        $minute = date ('i', $unix_time);
        $second = date ('s', $unix_time);
echo "
<td>
<span id='auct_timer'>
         
</span>
         
<script language='javascript'>
countdown(".$year.",".$month.",".$day.",".$hour.",".$minute.",".$second.")
</script>
</td>
";

Код же кривой - кавычки одинакового типа друг в друга вкладываешь.

Это где?

Erolast 19.03.2014 17:32

Цитата:

Это где?

Цитата:

echo "
Цитата:

countdown(".$year."
Здесь.

Drugpunker 19.03.2014 17:38

Цитата:

Сообщение от Erolast (Сообщение 303258)
http://javascript.ru/Date


Методы объекта date в статье по ссылке выше подробно перечислены.

Это я понимаю. Почему числа, переданные в функцию меняются?

Erolast 19.03.2014 17:40

Цитата:

Это я понимаю. Почему числа, переданные в функцию меняются?
Потому-что конструктор Date при обработке UNIX-времени почему-то работает с миллисекундами, а не с секундами. Умножай на 1000.

В итоге код таким должен быть:
<?
$t=time();
echo "
<script>
var unixtime = parseInt('$t')*1000;
var dateObj = new Date(unixtime);
alert('Сейчас '+dateObj.getHours()+' часов!');
</script>
"
?>

Drugpunker 19.03.2014 17:51

Спасибо, позже надо попробовать.
В данный момент ненавижу всё что связано с компьютером :)

Drugpunker 20.03.2014 16:03

Всем снова здравствуйте.

Заработал таки таймер у меня.
Но, проблему с выполнением нескольких таймеров так и не решил.

Срабатывает только последний из всех.
  • В цикле PHP выдаются таблицы с событиями, которые произойдут в конкретные Дату и Время.
  • Соответственно, напротив каждого события должен висеть таймер обратного отсчёта

Моя реализация:
  1. Кусок кода PHP(в цикле):
    выбираю данные из базы и применяю к ним функцию countdown()
$unix_date = $row_auct_select->start_date;
		$unix_time = $row_auct_select->start_time;
		$day = date ('d', $unix_date);
		$month = date ('n', $unix_date);
		$year = date('Y', $unix_date);
		$time = date ('H:i:s', $unix_time);
echo "
<td>

<span id='$Zapros_iz_bd_(id_продукта)'>
		
</span>

<script language='javascript'>
countdown(".$unix_date.",".$unix_time.",".$Zapros_iz_bd_(id_продукта)."</script>
	
</td>
";

  1. Собственно, функция на JS:

function countdown(a_date,a_time,a_id)
{
	span_id = document.getElementById(a_id);
	montharray = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	auct_date = new Date(parseInt(a_date) * 1000);
	auct_time = new Date(parseInt(a_time) * 1000);
	
	var auct_year = auct_date.getYear(); if (auct_year < 1000) auct_year += 1900
    var auct_month  = auct_date.getMonth()
    var auct_day = auct_date.getDate()
    var auct_hour = auct_time.getHours()
    var auct_minute = auct_time.getMinutes()
    var auct_second = auct_time.getSeconds()

    var futurestring = montharray[auct_month]+" "+auct_day+", "+auct_year+" "+auct_hour+":"+auct_minute+":"+auct_second
  
    function calculate()
	{
		res = Date.parse(futurestring) - new Date()
                res_day = Math.floor(res/(60*60*1000*24)*1)
                res_hour = Math.floor((res%(60*60*1000*24))/(60*60*1000)*1)
                res_min = Math.floor(((res%(60*60*1000*24))%(60*60*1000))/(60*1000)*1)
                res_sec = Math.floor((((res%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1)

			if (res > 0) 
		    {
				span_id.innerHTML = res_day+" д. "+"<br/>"+res_hour+":"+res_min+":"+res_sec
                setTimeout( calculate ,1000);
		    }
		    else
		    {
				span_id.innerHTML = "Всё проехали";
		    }
 
		
	}
	calculate();

}

  • Идентификатор каждого SPAN уникальный, но всё равно работает только в последней таблице...........?
  • И как реализовать так, чтобы надпись по истечении времени таймера не "передёргивалась", не попадала в цикл функции JS?
    В данной реализации надпись висит секунду, а затем наследует предыдущий таймер...

Видел похожие примеры, но так и не смог добиться поставленной задачи;)

рони 20.03.2014 17:17

Drugpunker,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  div{
    background-color: #00FFFF;
     height: 50px;
     color: #0000FF;
  }

  </style>
</head>

<body>
<div id="test"></div>
<div id="test1"></div>
 <script>
     function countdown(a_date,a_time,a_id)
{
	span_id = document.getElementById(a_id);
	montharray = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	auct_date = new Date(parseInt(a_date) * 1000);
	auct_time = new Date(parseInt(a_time) * 1000);

	var auct_year = auct_date.getYear(); if (auct_year < 1000) auct_year += 1900
    var auct_month  = auct_date.getMonth()
    var auct_day = auct_date.getDate()
    var auct_hour = auct_time.getHours()
    var auct_minute = auct_time.getMinutes()
    var auct_second = auct_time.getSeconds()

    var futurestring = montharray[auct_month]+" "+auct_day+", "+auct_year+" "+auct_hour+":"+auct_minute+":"+auct_second

    function calculate(elem)
	{
	  var res = Date.parse(futurestring) - new Date()
                res_day = Math.floor(res/(60*60*1000*24)*1)
                res_hour = Math.floor((res%(60*60*1000*24))/(60*60*1000)*1)
                res_min = Math.floor(((res%(60*60*1000*24))%(60*60*1000))/(60*1000)*1)
                res_sec = Math.floor((((res%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1)

			if (res > 0)
		    {
				elem.innerHTML = res_day+" д. "+"<br/>"+res_hour+":"+res_min+":"+res_sec
                setTimeout( function h()
{
   calculate(elem)
},1000);
		    }
		    else
		    {
				elem.innerHTML = "Всё проехали";
		    }


	}
	calculate(span_id);

}
  countdown(new Date()/1000,new Date()/1000+15,'test')
  countdown(new Date()/1000,new Date()/1000+5,'test1')

 </script>
</body>

</html>

Drugpunker 20.03.2014 17:24

Ох ты, круто!

Пытался сделать подобное, не получилось...

А если я не знаю сколько блоков будут выводиться?
Как то в цикле вывод функций, применяемых к выводимым блокам можно сделать...на этом я и сломался...

рони 20.03.2014 17:34

Цитата:

Сообщение от Drugpunker
А если я не знаю сколько блоков будут выводиться?
Как то в цикле вывод функций, применяемых к выводимым блокам можно сделать

непонял ничего

Drugpunker 21.03.2014 07:59

Цитата:

Сообщение от рони (Сообщение 303433)
непонял ничего

Если id, блоку с таймером задаётся динамически, т. е. туда помещается id товара, к которому применяется таймер.
В коде JS функция применяется к конкретному id, конкретного блока.
Так?
И каждая функция добавляется вручную.

Как сделать, чтобы количество функций, применяемых к блокам (количество которых заведомо неизвестно) с таймерами определялось автоматически, средствами JS то бишь?

рони 21.03.2014 08:49

Drugpunker,
присвоить нужным блокам класс и в атрибут дата занести данные для таймера -- потом по готовности страницы обойти все блоки с данным классом и установить таймеры.

Drugpunker 21.03.2014 08:52

Спасибо разобрался, можно было и не задавать вопрос, поспешил не подумав.

Ох и намучился я с этим таймером.

Ещё раз спасибо...


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