JS onunload事件并不总是有效

时间:2010-11-29 19:31:32

标签: javascript time counter onunload

我想计算访问者在某个页面上花费的时间并将其存储在我的MySQL数据库中。

我想在window.onload上启动计时器就像这样:

window.onload= startCount;
window.onunload= sendCount;

var b=0;
var y;
function startCount() {
    document.getElementById('livecount').innerHTML=b;
    b=b+1;
    y=setTimeout("startCount()",1000);
}

在访问者离开页面(window.onunload)之后,我通过XMLHttpRequest将时间发送到PHP文件,该文件将它存储在我的数据库中:

function sendCount() {
    clearTimeout(y);    
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }  
xmlhttp.open("GET","count.php?q="+b,true);
xmlhttp.send();
}

问题是它并不总是有效。我会说它的效果就像我尝试过的10次中的3次。 是不是没有足够的时间让PHP和SQL完全执行?

5 个答案:

答案 0 :(得分:4)

由于onunload不可靠,我会考虑使用AJAX解决方案。我根本不是这方面的专家,但想到的是每隔一段时间对你的柜台进行一次ping操作。我不会每秒都打你的柜台,因为这似乎过分了。

我会将时间分解为您关心的持续时间,例如<5秒,<30秒,<1分钟,<5分钟,5分钟以上。

然后我会像这样编写一段JavaScript:

window.onload = soCounter;

var iter=0;
var times=[0,5,30,60,300];  // Your duration choices

function doCounter() {

    sendCountPing(times(iter));

    iter++;

    if(iter < times.length) {
        setTimeout(doCounter, times[iter]*1000);
    }
} 

function sendCountPing(dur) {
    if (window.XMLHttpRequest)
    {  // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {  // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }  

    xmlhttp.open("GET","count.php?q="+b,true);
    xmlhttp.send();

}

诀窍在于,对于发送的每个count.php?q=30,您需要从count.php?q=5计数中减去一个。这不一定是程序化的,很容易进行后期处理。

澄清一下,如果你有3个访客,一个花3秒,一个花20秒,一个花30分钟,你会看到以下数量:

  0:  3   // 3 people spent at least 0 seconds
  5:  2   // 2 people spent at least 5 seconds
 30:  1
 60:  1
300:  1   // 1 person spent at least 5 minutes

有意义吗?

答案 1 :(得分:1)

当onload处理程序运行时,页面正在被删除。我不确定您对DOM或其​​他服务的状态有什么保证,但您当然不能指望异步事件或超时触发。虽然不是标准的一部分,但今天大多数(全部?)浏览器都提供了一个onbeforeunload钩子,其工作方式与其他事件处理程序的工作方式大致相同,只是如果您愿意,还可以返回false来取消卸载。

答案 2 :(得分:1)

您可以根据建议设置一个计时器,该计时器可以根据需要运行(几秒钟左右),并将信息存储在cookie(或cookie)中。如果您想要执行的操作不仅仅是向用户显示值,您可以将此信息发送到服务器。因此,不要在每个周期将其发送到服务器,只需将其发送到服务器,当您想要对该信息执行某些操作时(例如向用户显示他在您网站上的各个页面上花费的所有时间的列表)。 / p>

答案 3 :(得分:0)

onunload不是一种可靠的跟踪方式......好吧,几乎任何东西。 例如,请参阅http://www.google.com/support/forum/p/Google+Analytics/thread?tid=6496cd5d4b627c0e&hl=en

就解决问题而言,最好的方法是跟踪用户上次在页面上的时间。例如,每隔一分钟从客户端调用跟踪器。 Google Analytics等分析系统实际上只是假设用户在提供的最后一页之后离开了。即如果我阅读页面,然后点击某些东西,它会刷新计数器。但如果没有后续的命中发生,那就意味着我离开了。

答案 4 :(得分:0)

另一种选择是将数据保存在localStorage / cookie中,并在用户下次访问网站时发送;假设用户留下或曾经回到您的网站。

最好使用Date() calc而不是setInterval/setTimeout来计算时间 最好使用addEventListener代替onload = func

sendPreviousStats();
window.addEventListener('load',loadFunc);
window.addEventListener('unload',leaveFunc);

function loadFunc() {
    window.startTime = new Date();
}

function leaveFunc() {
    var msec = new Date().getTime()-window.startTime.getTime();
    var seconds = Math.round(msec/1000);
    localStorage.setItem('leaveSeconds',seconds);
}

function sendPreviousStats() {
    var duration = localStorage.getItem('leaveSeconds');
    if (duration !== null && duration !== undefined) {
        localStorage.removeItem('leaveSeconds');
        sendCountPing(duration);
    }
}