javascript计时器/持续时间在

时间:2018-01-12 02:01:37

标签: javascript php jquery html timer

几天前,我发现了一个代码,我认为我可以用它来计算用户的登录时间..但是在我的应用程序中测试后,我发现那里有一个' sa之后的时间差异。所以,我决定使用名为" "的Staying Alive for Google Chrome扩展程序,它完美地工作了#34;或者我希望... ...说实话,它有点儿好",但在那之后我发现了与附图相同的问题。  enter image description here

以及的代码我找到了:

/*===============*/

var seconds = 0; 
var minutes = 0;
var hours = 0;
var t;

function add() {
    seconds++;
    if (seconds >= 60) {
        seconds = 0;
        minutes++;
        if (minutes >= 60) {
            minutes = 0;
            hours++;
        }
    }

    $('#totalTime').html ( "" + (hours ? (hours > 9 ? hours : "0" + hours) : "00") + ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":" + (seconds > 9 ? seconds : "0" + seconds) );

    timer();
}

function timer() {
    t = setTimeout(add, 1000);
}
/*===============*/

所以,我希望有人可以帮助我,如何使计时器运行得体,或者有更好的解决方案,因为我在此页面中超过6个计时器 ..

P.S。此应用程序使用进行编码,并且我在同一页面中每运行5000毫秒进行一次调用。

P.P.S。我的一位朋友建议,但我真的不太了解它。

非常感谢

2 个答案:

答案 0 :(得分:2)

由于JavaScript在浏览器中的单个线程中执行,因此预期会出现此行为。基本上,setTimeout和setInterval函数的延迟量应该被视为 minimum

例如,如果你要执行一个导致大量DOM操作的函数,这可能会推迟回调的执行。

有关此主题的更多信息,请阅读John Resig的帖子on the the execution order of JavaScript timers

您朋友的建议可以提供解决方案,因为WebWorkers在不同的线程中执行,因此阻止DOM操作的主观性较差。但是,我建议您在服务器端处理时间计算。例如,通过在数据库中创建流的条目,该数据库至少包含流的开始日期和时间。然后:

  1. 让您的JavaScript应用程序轮询服务器以同步时间
  2. 或者,最好使用WebSocket设置流连接。

答案 1 :(得分:1)

测量时间的最佳方法是在开始时保存系统时钟的值(由Date-Object提供),并从当前时间戳中减去它。

一个例子:

const totalTime = document.querySelector('#totalTime');
const startTime = Date.now();

function updateClock() {
  // JS Date counts in ms, divide by 1000 to get seconds
  // |0 does the same as Math.floor(value)
  const elapsedTime = (Date.now() - startTime) / 1000 |0;
  const seconds = elapsedTime % 60;
  const minutes = Math.floor(elapsedTime / 60) % 60;
  const hours = Math.floor(elapsedTime / 3600) % 24;
  
  totalTime.textContent = 
    (hours < 10 ? '0' : '') + hours + ':' +
    (minutes < 10 ? '0' : '') + minutes + ':' +
    (seconds < 10 ? '0' : '') + seconds;
}

window.setInterval(updateClock, 1000);
<div id="totalTime"></div>

编辑1“来自询问”:

的人

我对你的代码进行了一些编辑,我需要添加一些选项(重置,暂停和恢复) 我认为它可以帮助任何人,所以我发布它...

class Clock {
	constructor(element, offset = 0) {
		if(!(element && element instanceof HTMLElement))
			throw new Error('Parameter element must be a valid HTML Element');
		
		this._startTime = 0;
		this._offset = offset;
		this._interval = null;
		this._element = element;
	}

	tick() {
		const elapsedTime = (Date.now() - this._startTime) / 1000 |0;
		const seconds = elapsedTime % 60;
		const minutes = elapsedTime / 60 % 60 |0;
		const hours = elapsedTime / 3600 % 24 |0;
		
		this._element.textContent = 
			(hours < 10 ? '0' : '') + hours + ':' +
			(minutes < 10 ? '0' : '') + minutes + ':' +
			(seconds < 10 ? '0' : '') + seconds;
	}

	pause () {
		if(this._interval) {
			this._offset = Date.now() - this._startTime;
			window.clearInterval(this._interval);
			this._interval = null;
		}
	}

	resume () {
		if(!this._interval) {
			this._startTime = Date.now() - this._offset;
			this._interval = setInterval(this.tick.bind(this), 1000);
			this.tick();
		}
	}

	reset () {
		this.pause();
		this._offset = 0;
		this._element.textContent = '00:00:00';
	}
};

let clock = new Clock(document.querySelector('#totalTime'), 30000);
document.querySelector('#pause').addEventListener('click', () => { clock.pause() });
document.querySelector('#resume').addEventListener('click', () => { clock.resume() });
document.querySelector('#reset').addEventListener('click', () => { clock.reset() });
clock.resume();
<div id="totalTime"></div>
<button id="pause">Pause</button>
<button id="resume">Resume</button>
<button id="reset">Reset</button>