如何向 DOM 一种元素提供或定位不同的数据,以及如何管理/维护每个元素的重新渲染/更新周期?
How does one provide or target different data to DOM elements of one kind and does manage / maintain each of an element's rerender / update cycle?
我正在我的 wordpress 网站上的一个页面上工作,我从后端提取数据。数据有一个 end_date
列,我用它来显示倒数计时器,即从当前日期时间到 end_date
。
我是这样处理的:
这是将显示计时器的 html 元素:
<div class="t1-auction-timer"></div>
这是创建计时器的javascript:
var countDownDate = new Date("<?=$endDate?>").getTime();
var x = setInterval(function() {
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);
var timer = document.querySelectorAll(".t1-auction-timer");
for (var i = 0; i < timer.length; i++)
{
timer[i].innerHTML = '<ul class="clock-value"><li class="clock-days">' + padNumber(days) + '<small>days</small> </li><li class="clock-separator">:</li><li class="clock-hours"> ' + padNumber(hours) + ' <small>hrs</small> </li><li class="clock-separator">:</li><li class="clock-minutes"> ' + padNumber(minutes) + ' <small>min</small> </li><li class="clock-separator">:</li><li class="clock-seconds"> ' + padNumber(seconds) + ' <small>sec</small> </li></ul>';
}
if ( distance < 0 )
{
clearInterval(x);
for (var i = 0; i < timer.length; i++)
{
timer[i].innerHTML = "EXPIRED";
}
}
}, 1000);
function padNumber(number)
{
if( number == 0 )
{
number = "0" + number;
}
else if( number > 9 )
{
number;
}
else
{
number = "0" + number;
}
return number;
}
<?=$endDate?>
变量是从php传递过来的。它被正确传递。
根据数据库中的记录,要显示的计时器数量将是动态的。我面临的问题是:我只能从第一条记录中创建计时器。它在页面上显示的所有帖子中重复。我怀疑这与我的 .t1-auction-timer
class 循环有关,但我还没有弄明白。
直接使用大量 OP 代码的方法几乎没有改变,在一个时间间隔内,通过一次又一次地(重新)渲染每个计时器来处理一组计时器元素。
计时器元素的标记基础将是上面(在评论中)提到的 <time/>
元素,其中 OP 的 endDate
将从该元素的 datetime
属性(也一次又一次)...
function padNumber(number) {
return (number >= 10) && number || `0${ number }`;
}
function updateTimer(nodeList, timer, timerData) {
// GUARD
if (timer.dataset.isExpired === "true") {
return;
}
const countDownDate = new Date(timer.dateTime).getTime();
const now = new Date().getTime();
const distance = countDownDate - now;
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const 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);
if (distance >= 0) {
timer.innerHTML = `<ul class="clock-value">
<li class="clock-days">${ padNumber(days) } <small>days</small></li>
<li class="clock-hours">${ padNumber(hours) } <small>hrs</small></li>
<li class="clock-minutes">${ padNumber(minutes) } <small>min</small></li>
<li class="clock-seconds">${ padNumber(seconds) } <small>sec</small></li>
</ul>`;
} else {
timer.innerHTML = "EXPIRED";
timer.dataset.isExpired = "true";
// clear the interval only in case each timer has been expired.
if ([
...nodeList
].every(elmNode =>
elmNode.dataset.isExpired === "true"
)) {
clearInterval(timerData.timerId);
}
}
}
function updateAllTimers(nodeList, timerData) {
nodeList.forEach(timer => updateTimer(nodeList, timer, timerData));
}
function initializeAllTimers() {
const nodeList = document.querySelectorAll('.t1-auction-timer');
const data = {
timerId: null
};
updateAllTimers(nodeList, data);
data.timerId = setInterval(updateAllTimers, 1000, nodeList, data);
}
initializeAllTimers();
body {
margin: 0;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 2px 10px 3px 10px;
}
li .auction-name {
font-family: courier;
}
ul.clock-value,
ul.clock-value > li {
padding: 0;
display: inline-block;
}
ul.clock-value > li {
font-family: ui-monospace;
}
ul.clock-value li:not(:last-child) small:after {
content: ":";
display: inline-block;
width: .7em;
font-weight: bold;
text-align: right;
}
<ul>
<li>
Auction <span class="auction-name">Foo</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-21 22:15">2020-12-21 22:15</time>
</li>
<li>
Auction <span class="auction-name">Bar</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 03:15">2020-12-22 03:15</time>
</li>
<li>
Auction <span class="auction-name">Baz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 11:30">2020-12-22 11:30</time>
</li>
<li>
Auction <span class="auction-name">Biz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 14:45">2020-12-22 14:45</time>
</li>
<li>
Auction <span class="auction-name">Buz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-23 10:20">2020-12-23 10:20</time>
</li>
<li>
Auction <span class="auction-name">Fiz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-24 10:55">2020-12-24 10:55</time>
</li>
<li>
Auction <span class="auction-name">Faz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2021-01-04 16:15">2021-01-04 16:15</time>
</li>
</ul>
上述方法可能会更改为创建一个已经预渲染的计时器组件列表,其中每个组件的更新不再基于将一大块总是新创建的 HTML 标记分配给 DOM节点的innerHTML
.
为了更通用/更灵活地使用此类组件,现在可以将自定义计时器标记的模板字符串以及自定义“已过期”消息传递给初始化方法。此外,任何组件现在都由其 data-countdown-component
属性标识,这使得创建/初始化过程独立于任何强制或仅与布局相关的 CSS class-names.
function emptyElementNode(elmNode) {
Array
.from(elmNode.childNodes)
.forEach(node => node.remove());
}
function createTemplateFromMarkup(templateMarkup) {
const container = document.createElement('div');
container.innerHTML = String(templateMarkup);
return container.firstElementChild;
}
function getTimeMeasureFromMilliseconds(value) {
let days = (value / 3600000 / 24);
let hours = ((days - Math.floor(days)) * 24);
let minutes = ((hours - Math.floor(hours)) * 60);
let seconds = ((minutes - Math.floor(minutes)) * 60);
days = Math.floor(days);
hours = Math.floor(hours);
minutes = Math.floor(minutes);
seconds = Math.floor(seconds + 0.001);
seconds = ((seconds < 60) && seconds) || 0;
minutes = ((minutes < 60) && minutes) || 0;
hours = ((hours < 24) && hours) || 0;
return { days, hours, minutes, seconds };
}
function formatMeasure(value) {
return ((value >= 10) && value || `0${ value }`);
}
function createTimerComponent(rootNode, template, expiredMessage) {
const expirationDate = new Date(rootNode.dateTime);
const [
elmDays,
elmHours,
elmMinutes,
elmSeconds
] = [...template.querySelectorAll([
'[data-countdown-days]',
'[data-countdown-hours]',
'[data-countdown-minutes]',
'[data-countdown-seconds]',
].join(','))];
const component = {
rootNode,
elmDays,
elmHours,
elmMinutes,
elmSeconds,
isExpired: false,
expiredMessage,
expiresTimestamp: expirationDate.getTime(),
};
emptyElementNode(component.rootNode);
rootNode.dateTime = expirationDate.toUTCString();
rootNode.appendChild(template);
return component;
}
function updateTimer(componentList, component, timerData) {
// GUARD
if (component.isExpired) {
return;
}
const { dateNow } = timerData;
const { expiresTimestamp } = component;
const { elmDays, elmHours, elmMinutes, elmSeconds } = component;
const time = (expiresTimestamp - dateNow);
if (time >= 0) {
const measures = getTimeMeasureFromMilliseconds(time);
elmSeconds.textContent = formatMeasure(measures.seconds);
elmMinutes.textContent = formatMeasure(measures.minutes);
elmHours.textContent = formatMeasure(measures.hours);
elmDays.textContent = formatMeasure(measures.days);
} else {
component.isExpired = true;
emptyElementNode(component.rootNode);
component.rootNode.textContent = component.expiredMessage;
// clear the interval only in case each timer has been expired.
if (componentList.every(item => item.isExpired)) {
clearInterval(timerData.timerId);
}
}
}
function updateAllTimers(componentList, timerData) {
timerData.dateNow = Date.now();
componentList.forEach(component =>
updateTimer(componentList, component, timerData)
);
}
function initializeAllTimers(templateMarkup, expiredMessage = 'Closed') {
const defaultTemplateMarkup = [
'<span>',
'<span data-countdown-days></span> <small>days</small>, ',
'<span data-countdown-hours></span> <small>hours</small>, ',
'<span data-countdown-minutes></span> <small>minutes</small>, ',
'<span data-countdown-seconds></span> <small>seconds</small>',
'</span>',
].join('');
let template = createTemplateFromMarkup(templateMarkup);
if (!template || template.querySelectorAll([
'[data-countdown-days]',
'[data-countdown-hours]',
'[data-countdown-minutes]',
'[data-countdown-seconds]',
].join(',')).length !== 4) {
template = createTemplateFromMarkup(defaultTemplateMarkup);
}
const componentList = [
...document.querySelectorAll('[data-countdown-component]')
].map(elmNode =>
createTimerComponent(elmNode, template.cloneNode(true), expiredMessage)
);
const data = {
timerId: null,
dateNow: null,
};
updateAllTimers(componentList, data);
data.timerId = setInterval(updateAllTimers, 1000, componentList, data);
}
initializeAllTimers(`<ul class="clock-value">
<li class="clock-days">
<span data-countdown-days></span> <small>days</small>
</li>
<li class="clock-hours">
<span data-countdown-hours></span> <small>hours</small>
</li>
<li class="clock-minutes">
<span data-countdown-minutes></span> <small>minutes</small>
</li>
<li class="clock-seconds">
<span data-countdown-seconds></span> <small>seconds</small>
</li>
</ul>`, 'Expired');
body {
margin: 0;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 2px 10px 3px 10px;
}
li .auction-name {
font-family: courier;
}
ul.clock-value,
ul.clock-value > li {
padding: 0;
display: inline-block;
}
ul.clock-value > li {
font-family: ui-monospace;
}
ul.clock-value li:not(:last-child) small:after {
content: ":";
display: inline-block;
width: .7em;
font-weight: bold;
text-align: right;
}
<ul>
<li>
Auction <span class="auction-name">Foo</span> expires at/in ...
<time data-countdown-component datetime="2020-12-21 22:15">2020-12-21 22:15</time>
</li>
<li>
Auction <span class="auction-name">Bar</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 03:15">2020-12-22 03:15</time>
</li>
<li>
Auction <span class="auction-name">Baz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 11:30">2020-12-22 11:30</time>
</li>
<li>
Auction <span class="auction-name">Biz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 14:45">2020-12-22 14:45</time>
</li>
<li>
Auction <span class="auction-name">Buz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-23 10:20">2020-12-23 10:20</time>
</li>
<li>
Auction <span class="auction-name">Fiz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-24 10:55">2020-12-24 10:55</time>
</li>
<li>
Auction <span class="auction-name">Faz</span> expires at/in ...
<time data-countdown-component datetime="2021-01-04 16:15">2021-01-04 16:15</time>
</li>
</ul>
您可以尝试这种使用 data
属性的方法。
var auctionTimer = document.getElementsByClassName('t1-auction-timer');
var interval = setInterval(function() {
if(auctionTimer.length == 0 ){clearFunction()}
for(var i= 0; i < auctionTimer.length; i++){
var endDate = auctionTimer[i].getAttribute('data-end-date')
var int = createTimer(endDate, auctionTimer[i]);
}
},1000)
function clearFunction() {
clearInterval(interval);
}
function createTimer(endDate, element){
var countDownDate = new Date(endDate).getTime();
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);
element.innerHTML = '<ul class="clock-value"><li class="clock-days">' + padNumber(days) + '<small>days</small> </li><li class="clock-separator">:</li><li class="clock-hours"> ' + padNumber(hours) + ' <small>hrs</small> </li><li class="clock-separator">:</li><li class="clock-minutes"> ' + padNumber(minutes) + ' <small>min</small> </li><li class="clock-separator">:</li><li class="clock-seconds"> ' + padNumber(seconds) + ' <small>sec</small> </li></ul>';
if ( distance < 0 )
{
if ( element.classList.contains("t1-auction-timer") ){
element.classList.remove("t1-auction-timer")
element.classList.add("expierd")
expierd()
}
}
}
function padNumber(number)
{
if( number == 0 )
{
number = "0" + number;
}
else if( number > 9 )
{
number;
}
else
{
number = "0" + number;
}
return number;
}
function expierd(){
var expierdDate = document.getElementsByClassName('expierd');
for(var i= 0; i < expierdDate.length; i++){
expierdDate[i].innerHTML = "expierd"
}
}
<div class="t1-auction-timer" data-end-date="2021-01-03 16:15"></div>
<div class="t1-auction-timer" data-end-date="2021-01-01 16:15"></div>
<div class="t1-auction-timer" data-end-date="2021-01-04 16:15"></div>
我正在我的 wordpress 网站上的一个页面上工作,我从后端提取数据。数据有一个 end_date
列,我用它来显示倒数计时器,即从当前日期时间到 end_date
。
我是这样处理的:
这是将显示计时器的 html 元素:
<div class="t1-auction-timer"></div>
这是创建计时器的javascript:
var countDownDate = new Date("<?=$endDate?>").getTime();
var x = setInterval(function() {
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);
var timer = document.querySelectorAll(".t1-auction-timer");
for (var i = 0; i < timer.length; i++)
{
timer[i].innerHTML = '<ul class="clock-value"><li class="clock-days">' + padNumber(days) + '<small>days</small> </li><li class="clock-separator">:</li><li class="clock-hours"> ' + padNumber(hours) + ' <small>hrs</small> </li><li class="clock-separator">:</li><li class="clock-minutes"> ' + padNumber(minutes) + ' <small>min</small> </li><li class="clock-separator">:</li><li class="clock-seconds"> ' + padNumber(seconds) + ' <small>sec</small> </li></ul>';
}
if ( distance < 0 )
{
clearInterval(x);
for (var i = 0; i < timer.length; i++)
{
timer[i].innerHTML = "EXPIRED";
}
}
}, 1000);
function padNumber(number)
{
if( number == 0 )
{
number = "0" + number;
}
else if( number > 9 )
{
number;
}
else
{
number = "0" + number;
}
return number;
}
<?=$endDate?>
变量是从php传递过来的。它被正确传递。
根据数据库中的记录,要显示的计时器数量将是动态的。我面临的问题是:我只能从第一条记录中创建计时器。它在页面上显示的所有帖子中重复。我怀疑这与我的 .t1-auction-timer
class 循环有关,但我还没有弄明白。
直接使用大量 OP 代码的方法几乎没有改变,在一个时间间隔内,通过一次又一次地(重新)渲染每个计时器来处理一组计时器元素。
计时器元素的标记基础将是上面(在评论中)提到的 <time/>
元素,其中 OP 的 endDate
将从该元素的 datetime
属性(也一次又一次)...
function padNumber(number) {
return (number >= 10) && number || `0${ number }`;
}
function updateTimer(nodeList, timer, timerData) {
// GUARD
if (timer.dataset.isExpired === "true") {
return;
}
const countDownDate = new Date(timer.dateTime).getTime();
const now = new Date().getTime();
const distance = countDownDate - now;
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const 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);
if (distance >= 0) {
timer.innerHTML = `<ul class="clock-value">
<li class="clock-days">${ padNumber(days) } <small>days</small></li>
<li class="clock-hours">${ padNumber(hours) } <small>hrs</small></li>
<li class="clock-minutes">${ padNumber(minutes) } <small>min</small></li>
<li class="clock-seconds">${ padNumber(seconds) } <small>sec</small></li>
</ul>`;
} else {
timer.innerHTML = "EXPIRED";
timer.dataset.isExpired = "true";
// clear the interval only in case each timer has been expired.
if ([
...nodeList
].every(elmNode =>
elmNode.dataset.isExpired === "true"
)) {
clearInterval(timerData.timerId);
}
}
}
function updateAllTimers(nodeList, timerData) {
nodeList.forEach(timer => updateTimer(nodeList, timer, timerData));
}
function initializeAllTimers() {
const nodeList = document.querySelectorAll('.t1-auction-timer');
const data = {
timerId: null
};
updateAllTimers(nodeList, data);
data.timerId = setInterval(updateAllTimers, 1000, nodeList, data);
}
initializeAllTimers();
body {
margin: 0;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 2px 10px 3px 10px;
}
li .auction-name {
font-family: courier;
}
ul.clock-value,
ul.clock-value > li {
padding: 0;
display: inline-block;
}
ul.clock-value > li {
font-family: ui-monospace;
}
ul.clock-value li:not(:last-child) small:after {
content: ":";
display: inline-block;
width: .7em;
font-weight: bold;
text-align: right;
}
<ul>
<li>
Auction <span class="auction-name">Foo</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-21 22:15">2020-12-21 22:15</time>
</li>
<li>
Auction <span class="auction-name">Bar</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 03:15">2020-12-22 03:15</time>
</li>
<li>
Auction <span class="auction-name">Baz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 11:30">2020-12-22 11:30</time>
</li>
<li>
Auction <span class="auction-name">Biz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-22 14:45">2020-12-22 14:45</time>
</li>
<li>
Auction <span class="auction-name">Buz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-23 10:20">2020-12-23 10:20</time>
</li>
<li>
Auction <span class="auction-name">Fiz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2020-12-24 10:55">2020-12-24 10:55</time>
</li>
<li>
Auction <span class="auction-name">Faz</span> expires at/in ...
<time class="t1-auction-timer" datetime="2021-01-04 16:15">2021-01-04 16:15</time>
</li>
</ul>
上述方法可能会更改为创建一个已经预渲染的计时器组件列表,其中每个组件的更新不再基于将一大块总是新创建的 HTML 标记分配给 DOM节点的innerHTML
.
为了更通用/更灵活地使用此类组件,现在可以将自定义计时器标记的模板字符串以及自定义“已过期”消息传递给初始化方法。此外,任何组件现在都由其 data-countdown-component
属性标识,这使得创建/初始化过程独立于任何强制或仅与布局相关的 CSS class-names.
function emptyElementNode(elmNode) {
Array
.from(elmNode.childNodes)
.forEach(node => node.remove());
}
function createTemplateFromMarkup(templateMarkup) {
const container = document.createElement('div');
container.innerHTML = String(templateMarkup);
return container.firstElementChild;
}
function getTimeMeasureFromMilliseconds(value) {
let days = (value / 3600000 / 24);
let hours = ((days - Math.floor(days)) * 24);
let minutes = ((hours - Math.floor(hours)) * 60);
let seconds = ((minutes - Math.floor(minutes)) * 60);
days = Math.floor(days);
hours = Math.floor(hours);
minutes = Math.floor(minutes);
seconds = Math.floor(seconds + 0.001);
seconds = ((seconds < 60) && seconds) || 0;
minutes = ((minutes < 60) && minutes) || 0;
hours = ((hours < 24) && hours) || 0;
return { days, hours, minutes, seconds };
}
function formatMeasure(value) {
return ((value >= 10) && value || `0${ value }`);
}
function createTimerComponent(rootNode, template, expiredMessage) {
const expirationDate = new Date(rootNode.dateTime);
const [
elmDays,
elmHours,
elmMinutes,
elmSeconds
] = [...template.querySelectorAll([
'[data-countdown-days]',
'[data-countdown-hours]',
'[data-countdown-minutes]',
'[data-countdown-seconds]',
].join(','))];
const component = {
rootNode,
elmDays,
elmHours,
elmMinutes,
elmSeconds,
isExpired: false,
expiredMessage,
expiresTimestamp: expirationDate.getTime(),
};
emptyElementNode(component.rootNode);
rootNode.dateTime = expirationDate.toUTCString();
rootNode.appendChild(template);
return component;
}
function updateTimer(componentList, component, timerData) {
// GUARD
if (component.isExpired) {
return;
}
const { dateNow } = timerData;
const { expiresTimestamp } = component;
const { elmDays, elmHours, elmMinutes, elmSeconds } = component;
const time = (expiresTimestamp - dateNow);
if (time >= 0) {
const measures = getTimeMeasureFromMilliseconds(time);
elmSeconds.textContent = formatMeasure(measures.seconds);
elmMinutes.textContent = formatMeasure(measures.minutes);
elmHours.textContent = formatMeasure(measures.hours);
elmDays.textContent = formatMeasure(measures.days);
} else {
component.isExpired = true;
emptyElementNode(component.rootNode);
component.rootNode.textContent = component.expiredMessage;
// clear the interval only in case each timer has been expired.
if (componentList.every(item => item.isExpired)) {
clearInterval(timerData.timerId);
}
}
}
function updateAllTimers(componentList, timerData) {
timerData.dateNow = Date.now();
componentList.forEach(component =>
updateTimer(componentList, component, timerData)
);
}
function initializeAllTimers(templateMarkup, expiredMessage = 'Closed') {
const defaultTemplateMarkup = [
'<span>',
'<span data-countdown-days></span> <small>days</small>, ',
'<span data-countdown-hours></span> <small>hours</small>, ',
'<span data-countdown-minutes></span> <small>minutes</small>, ',
'<span data-countdown-seconds></span> <small>seconds</small>',
'</span>',
].join('');
let template = createTemplateFromMarkup(templateMarkup);
if (!template || template.querySelectorAll([
'[data-countdown-days]',
'[data-countdown-hours]',
'[data-countdown-minutes]',
'[data-countdown-seconds]',
].join(',')).length !== 4) {
template = createTemplateFromMarkup(defaultTemplateMarkup);
}
const componentList = [
...document.querySelectorAll('[data-countdown-component]')
].map(elmNode =>
createTimerComponent(elmNode, template.cloneNode(true), expiredMessage)
);
const data = {
timerId: null,
dateNow: null,
};
updateAllTimers(componentList, data);
data.timerId = setInterval(updateAllTimers, 1000, componentList, data);
}
initializeAllTimers(`<ul class="clock-value">
<li class="clock-days">
<span data-countdown-days></span> <small>days</small>
</li>
<li class="clock-hours">
<span data-countdown-hours></span> <small>hours</small>
</li>
<li class="clock-minutes">
<span data-countdown-minutes></span> <small>minutes</small>
</li>
<li class="clock-seconds">
<span data-countdown-seconds></span> <small>seconds</small>
</li>
</ul>`, 'Expired');
body {
margin: 0;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 2px 10px 3px 10px;
}
li .auction-name {
font-family: courier;
}
ul.clock-value,
ul.clock-value > li {
padding: 0;
display: inline-block;
}
ul.clock-value > li {
font-family: ui-monospace;
}
ul.clock-value li:not(:last-child) small:after {
content: ":";
display: inline-block;
width: .7em;
font-weight: bold;
text-align: right;
}
<ul>
<li>
Auction <span class="auction-name">Foo</span> expires at/in ...
<time data-countdown-component datetime="2020-12-21 22:15">2020-12-21 22:15</time>
</li>
<li>
Auction <span class="auction-name">Bar</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 03:15">2020-12-22 03:15</time>
</li>
<li>
Auction <span class="auction-name">Baz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 11:30">2020-12-22 11:30</time>
</li>
<li>
Auction <span class="auction-name">Biz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-22 14:45">2020-12-22 14:45</time>
</li>
<li>
Auction <span class="auction-name">Buz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-23 10:20">2020-12-23 10:20</time>
</li>
<li>
Auction <span class="auction-name">Fiz</span> expires at/in ...
<time data-countdown-component datetime="2020-12-24 10:55">2020-12-24 10:55</time>
</li>
<li>
Auction <span class="auction-name">Faz</span> expires at/in ...
<time data-countdown-component datetime="2021-01-04 16:15">2021-01-04 16:15</time>
</li>
</ul>
您可以尝试这种使用 data
属性的方法。
var auctionTimer = document.getElementsByClassName('t1-auction-timer');
var interval = setInterval(function() {
if(auctionTimer.length == 0 ){clearFunction()}
for(var i= 0; i < auctionTimer.length; i++){
var endDate = auctionTimer[i].getAttribute('data-end-date')
var int = createTimer(endDate, auctionTimer[i]);
}
},1000)
function clearFunction() {
clearInterval(interval);
}
function createTimer(endDate, element){
var countDownDate = new Date(endDate).getTime();
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);
element.innerHTML = '<ul class="clock-value"><li class="clock-days">' + padNumber(days) + '<small>days</small> </li><li class="clock-separator">:</li><li class="clock-hours"> ' + padNumber(hours) + ' <small>hrs</small> </li><li class="clock-separator">:</li><li class="clock-minutes"> ' + padNumber(minutes) + ' <small>min</small> </li><li class="clock-separator">:</li><li class="clock-seconds"> ' + padNumber(seconds) + ' <small>sec</small> </li></ul>';
if ( distance < 0 )
{
if ( element.classList.contains("t1-auction-timer") ){
element.classList.remove("t1-auction-timer")
element.classList.add("expierd")
expierd()
}
}
}
function padNumber(number)
{
if( number == 0 )
{
number = "0" + number;
}
else if( number > 9 )
{
number;
}
else
{
number = "0" + number;
}
return number;
}
function expierd(){
var expierdDate = document.getElementsByClassName('expierd');
for(var i= 0; i < expierdDate.length; i++){
expierdDate[i].innerHTML = "expierd"
}
}
<div class="t1-auction-timer" data-end-date="2021-01-03 16:15"></div>
<div class="t1-auction-timer" data-end-date="2021-01-01 16:15"></div>
<div class="t1-auction-timer" data-end-date="2021-01-04 16:15"></div>