如何使用 window.setInterval 动态创建 HTMLElement 和更新 innerHTML
Posted
技术标签:
【中文标题】如何使用 window.setInterval 动态创建 HTMLElement 和更新 innerHTML【英文标题】:How to dynamically create HTMLElement and update innerHTML using window.setInterval 【发布时间】:2016-05-17 14:27:43 【问题描述】:我为倒计时时钟创建了以下脚本。我想动态创建 htmlElement (span) 并使用 window.setInterval 更新 innerHTML; 我的问题是更新当前日期而不创建新的跨度组。
这是我的代码:
var CountdownClock;
(function (CountdownClock)
var Countdown = (function ()
function Countdown(id, endDate, message)
this.id = id;
this.endDate = endDate;
this.message = message;
Countdown.appendChildElement = function (DOMNode, tagName)
var child = document.createElement(tagName);
DOMNode.appendChild(child);
return child;
;
Countdown.prototype.getTimeRemaining = function (enddate)
var t = Date.parse(enddate) - Date.parse(new Date().toString());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
;
;
Countdown.prototype.drawCountdown = function (id, enddate)
var container = document.getElementById(id);
var timeRemaining = this.getTimeRemaining(enddate);
var update = function ()
for (var key in timeRemaining)
if (timeRemaining.hasOwnProperty(key))
var span = Countdown.appendChildElement(container, 'span');
span.setAttribute('class', key);
span.innerHTML = timeRemaining[key];
;
return update();
;
Countdown.prototype.initialize = function ()
var that = this;
this.drawCountdown(that.id, that.endDate);
var update = setInterval((function ()
that.drawCountdown(that.id, that.endDate);
), 1000);
// var updateCountdown = setInterval(
// (function()
// that.initializeCountdown(that.id, that.endDate, that.message)
// ), 1000);
;
return Countdown;
)();
CountdownClock.Countdown = Countdown;
)(CountdownClock || (CountdownClock = ));
jsfiddle
【问题讨论】:
想想Date.parse(new Date().toString())
。它创建一个日期,将其转换为字符串,然后将其发送到 Date.parse 以转换为时间值(注意某些 Date 实现无法正确解析它们自己的字符串)。由于该表达式用于减法,因此只需考虑new Date()
。顺便说一句,这里使用 IIFE 是完全多余的,你创建一个全局 CountDown 对象然后向它添加属性,使用 IIFE 没有任何收获。
为了利用 IIFE,最初创建一次 span 并分配一个包含在闭包中的引用。然后在每次后续调用时更新它。
【参考方案1】:
创建一个函数来删除旧跨度
https://jsfiddle.net/7vjf4y5u/1/
我在 CountdownTimer 原型中添加了以下函数
/* Add a method to remove the old span*/
Countdown.prototype.removeSpan = function()
if(this.span)
this.span.remove();
;
并更新了以下函数以在创建新跨度后调用它
Countdown.prototype.drawCountdown = function(id, enddate)
var self = this; //Added this to reference in the update function
var container = document.getElementById(id);
var timeRemaining = this.getTimeRemaining(enddate);
var update = function()
for (var key in timeRemaining)
if (timeRemaining.hasOwnProperty(key))
var span = Countdown.appendChildElement(container, 'span');
span.setAttribute('class', key);
span.innerHTML = timeRemaining[key];
self.removeSpan(); //Remove the old span
self.span = span; //Set the new span
;
return update();
;
如果你不想每次都创建一个新的 span,只需保留一个 span 的引用并更新它的 innerHTML
https://jsfiddle.net/s3yzLvee/1/
Countdown.prototype.drawCountdown = function(id, enddate)
var self = this;
var container = document.getElementById(id);
var timeRemaining = this.getTimeRemaining(enddate);
var update = function()
for (var key in timeRemaining)
if (timeRemaining.hasOwnProperty(key))
/* Save a reference to the span*/
if(!self.span)
self.span = Countdown.appendChildElement(container, 'span');
//Operate on the referenced span
self.span.setAttribute('class', key);
self.span.innerHTML = timeRemaining[key];
;
return update();
;
【讨论】:
interface ChildNode 的 remove 方法只是新的,没有得到广泛支持,更好的支持是this.span.parentNode.removeChild(this.span)
。此外,旧的 span 可以被克隆和替换,但更新内容似乎更好。
@RobG 我只更新内容,在第二个示例中,将内容替换为self.span.innerHTML = timeRemaining[key];
@MagicJoseph 这对你有帮助吗?
好吧,我找到了另一个解决方案,但感谢大家的帮助。以上是关于如何使用 window.setInterval 动态创建 HTMLElement 和更新 innerHTML的主要内容,如果未能解决你的问题,请参考以下文章
如何在Angularjs上使用setInterval [重复]
如何使用定时器settimeout,setInterval执行能传递参数的函数
如何使用定时器settimeout,setInterval执行能传递参数的函数
如何使用定时器settimeout,setInterval执行能传递参数的函数