Я борюсь с реализацией несколько раз на одной странице.
Я сделал простой скрипт, отсчитывающий время до определенной даты, которая отличается для каждого div. Все это работает отлично и денди на одном div, но не работает на других.
Содержимое, в котором оно отображается, представляет собой загрузочную карточку. Я не знаю, сколько карточек будет на странице, так как они приходят в виде списка, поэтому я не могу жестко закодировать это.
<div class = "row">
<div th:each = " transport : ${transports}">
<div class = "card ml-1 mr-1 mt-3 mb-3 text-center text-primary">
<figure>
<div class = "card-body">
<h6 class = "card-text"><small class = "text-dark font-italic">Time till departure</small></h6>
<p class = "timer"><small class = "text-muted" id = "timer">Time till departure</small></p>
</div>
</figure>
</div>
</div>
Я знаю, что проблема заключается в id, но как мне динамически изменить id, чтобы он был уникальным для каждой карты?
Я использую Thymeleaf для создания шаблона.
Я пытался найти document.getElementsClassName("timer), но он не работает.
Я новичок в javascript, поэтому я думаю, что для этого есть наилучшая практика, но я не нашел ответа.
Спасибо за все советы.
<p class = "timer">
<small class = "text-muted" id = "timer">
Time till departure
</small></p>
<script th:inline = "javascript">
const countDownDate = new Date(/*[[${transport.departureDate}]]*/).getTime();
const x = setInterval(function () {
const now = new Date().getTime();
const distance = countDownDate - now;
onst days = Math.floor(distance / (1000 * 60 * 60 * 24));
onst hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("timer").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "EXPIRED";
}
}, 1000);
</script>
@lissettdm Я обновил код. Это список <Transport> transportList. В классе «Транспорт» есть поле «Дата отправления». Он должен показывать индивидуальный таймер для каждого экземпляра класса.
этот document.getElementsClassName("timer")
возвращает список узлов, который очень похож на массив, поэтому этот document.getElementsClassName("timer")[0]
захватит первый элемент в этом списке узлов
Чтобы создать уникальный идентификатор, вы можете использовать Date.now()
, это возвращает количество миллисекунд с 1 января 1970 года по настоящее время.
Вы можете использовать iterStat, чтобы получить индекс и создать уникальный идентификатор для каждой карты. Вы говорите, что каждая карта имеет разное время, это время является частью транспортного объекта, где вы храните информацию о времени?
@lissettdm, не могли бы вы уточнить? Я совершенно новичок в JS.
@KienHT вы имеете в виду document.getElementsByClassName("timer")[0].innerHTML? Потому что это не работает. Я новичок в JS, поэтому, возможно, я неправильно его реализую.
Конечно, я обновил свой ответ.
Попробуйте со статусом итерации. Таким образом вы можете получить значение индекса и определить уникальное имя класса для каждого элемента:
<div th:each = " transport, iterStat : ${transports}">
<div class = "card ml-1 mr-1 mt-3 mb-3 text-center text-primary">
<figure>
<div class = "card-body">
<h6 class = "card-text"><small class = "text-dark font-italic">Time till departure</small></h6>
<p th:id = "'timer-' + ${iterStat.index}"><small class = "text-muted" id = "timer">Time till departure</small></p>
<script th:inline = "javascript">
//...
const index=/*[[${iterStat.index}]]*/
document.getElementById(`timer-${index}').innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
//..
</script>
</div>
</figure>
</div>
</div>
Большое спасибо за ответ, но, к сожалению, я получаю исключение Не удалось разобрать как выражение: "'timer-'${iterStat.index}" (шаблон: "choose_transport" - строка 103, столбец 25) и должно ли это быть <p th:class = "'timer-'${iterStat.index}"> или <p th:id = "'timer-'${iterStat.index}">, поскольку document.getElementById ссылается на идентификатор
Извините, да должно быть (th:id = "'timer-' + ${iterStat.index}"). Я пропустил +. Я обновил свой ответ.
Таймер работает только с последним <div>. Столько времени на это потратил. Нужно перейти к другой задаче. Спасибо за ваше время, сэр.
Решено с помощью решения @lissetrdm, но все значения должны быть в функции.
<div th:each = " transport, iterStat : ${transports}">
<p class = "card-text" th:id = "'timer-' + ${iterStat.index}"><small class = "text-muted" id = "timer">Time till departure</small></p>
<script th:inline = "javascript">
var x = setInterval(function () {
var countDownDate = new Date(/*[[${transport.departureDate}]]*/).getTime();
var index = [[${iterStat.index}]];
console.info(index);
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById('timer-'+index).innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
document.getElementById('timer-'+index).innerHTML = "EXPIRED";
}
}, 1000);
</script>
Привет, как вы получаете эту карту и как вы вставляете эту карту в DOM?