HTML代码:
<body class="body" onload="buttonFunction(this)">
<form>
<p align="center"><strong>You have been on this page for </strong><input title="time spent on webpage" type="text" size="9" name="timespent"></p>
</form>
</body>
JS代码:
function buttonFunction() {
startday = new Date();
clockstart = startday.getTime();
initstopwatch();
getSecs();
}
function initstopwatch() {
var mytime = new Date();
var timeNow = mytime.getTime();
var timediff = timeNow - clockstart;
this.diffsecs = timediff/1000;
return(this.diffsecs);
}
function getSecs() {
var mySecs = initstopwatch();
var mySecs1 = ""+mySecs;
mySecs1= mySecs1.substring(0,mySecs1.indexOf("."))+ " secs. ";
document.forms[0].timespent.value = mySecs1;
window.setTimeout('getSecs()',1000);
}
现在,该函数应该计算用户在我的网页上的秒数并将该变量输入到输入框中。但是,它似乎什么都不做。那么这个功能有什么问题呢?
所以,让我们从头开始,因为我将能够以这种方式解释更多的事情。
首先,我们需要节省用户到达页面的时间。我们可以通过在加载页面后保存日期来完成此操作。
// The variable is outside because we need every function to
// be able to access it (like a global variable)
var userArrived;
// The function to initialize the counter
function initCounter(){
// Get the date when the user arrived
// here we do not use `var` because the variable exists
userArrived = new Date().getTime(); // This returns the date in milliseconds
}
// Wait the page to load
window.addEventListener('load', function(){
// Initialize the counter
initCounter();
}, false);
现在我们需要一个函数来给我们带来不同
function getCounterValue(){
// Calculate difference
var value = new Date().getTime() - userArrived;
// This variable now have the time the user
// is on the page in milliseconds
// Now we need to return the value to the caller
return value;
}
现在我们可以获得毫秒数,我们需要一个函数来将它们解析为人类可读的格式。
function parseMs2Sec(ms){
// We calculate seconds using seconds = milliseconds / 1000
// but we round it so that we don't have decimals
var sec = Math.round(ms/1000);
// Now we need to return the value to the caller
return sec;
}
现在唯一要做的就是每1秒钟(或更长时间)更新我们需要的任何视觉元素。
// Save the element on a variable for easy access
var timeSpent = document.forms[0].timespent;
// Update the screen with the latest time
function updateScreeenCounter(){
// Get the time the user is in the page
var ms = getCounterValue();
// Convert it to seconds
var sec = parseMs2Sec(ms);
// Display it in the page
timeSpent.value = sec + " sec.";
}
// Every 1000 milliseconds
setInterval(function(){
// Run function
updateScreeenCounter();
}, 1000);
// But this last code (with the interval)
// needs to run after the counter was initialized
// so we should put it inside the onload event we created.
这是演示中的漏洞代码:
//
// The variable is outside because we need every function to
// be able to access it (like a global variable)
var userArrived;
// The function to initialize the counter
function initCounter(){
// Get the date when the user arrived
// here we do not use `var` because the variable exists
userArrived = new Date().getTime(); // This returns the date in milliseconds
}
// Gives back the time since the user arrived on page (in ms)
function getCounterValue(){
// Calculate difference
var value = new Date().getTime() - userArrived;
// This variable now have the time the user
// is on the page in milliseconds
// Now we need to return the value to the caller
return value;
}
// Converts the given ms in the closest seconds
function parseMs2Sec(ms){
// We calculate seconds using seconds = milliseconds / 1000
// but we round it so that we don't have decimals
var sec = Math.round(ms/1000);
// Now we need to return the value to the caller
return sec;
}
// Update the screen with the latest time
function updateScreeenCounter(){
// Get the time the user is in the page
var ms = getCounterValue();
// Convert it to seconds
var sec = parseMs2Sec(ms);
// Display it in the page
document.forms[0].timespent.value = sec + " sec.";
}
// Wait the page to load
window.addEventListener('load', function(){
// Initialize the counter
initCounter();
// Every 1000 milliseconds
setInterval(function(){
// Run function
updateScreeenCounter();
}, 1000);
}, false);
<form>
<input name="timespent" value="Loading ..."/>
</form>
更多提示:
~~~编辑~~~
我忘了提到在这种情况下使用setInterval
更好,因为它比慢速计算机中的递归setTimeout
更准确。
Per Thanasis Grammatopoulos的评论,我之前的回答(如下)是错误的。我尝试通过修复分号positioining来运行代码,并在Safari中运行。
window.setTimeout('getSecs()',1000; )
应该
window.setTimeout('getSecs()',1000);
我之前的错误答案:setTimeout只会调用一次getSecs()。我想你想每秒调用一次,而不是一秒钟调用一次,在这种情况下你应该使用:
window.setInterval(getSecs,1000);
如果你想稍后停止间隔(可能是一个好主意),你可以这样做:
var interval = window.setInterval(getSecs,1000);
稍后当你想要停止计时器时,只需拨打:
clearInterval(interval);
基本上,setTimeout
应该用setInterval
替换(因为你想要重复调用getSecs
而不是一次)。那么,你期望传递给它的是对函数的引用而不是它的调用,所以getSecs
(没有引号或括号)而不是"getSecs()"
。而这很可能就是原因。我现在无法测试代码。问题是,getSecs()
不应该称自己,因为它将取决于setInterval
其次,代码值得进行大规模清理,但如果没有人提出一个好的重构,我明天就能提供更多的帮助。