如何衡量在页面上花费的时间?

时间:2011-01-12 09:24:50

标签: javascript jquery

我想测量用户在页面上花费的时间(以浮点数表示的整数或分钟数)。我知道有一个卸载事件,我可以在他们离开页面时触发。但是如何获得他们已经在那里度过的时间?

9 个答案:

答案 0 :(得分:44)

接受的答案是好的,但是(作为替代方案)我已经将一些工作放入一个小的JavaScript库中,该库计算用户在网页上的时间长度。它具有更准确(但并不完美)跟踪用户实际与页面交互的时间的额外好处。它会忽略用户切换到不同标签,闲置,最小化浏览器等的时间。在接受的答案中建议的Google Analytics方法有缺点(据我所知),它只会检查您的新请求何时处理域。它将先前的请求时间与新请求时间进行比较,并调用“在您的网页上花费的时间”。它实际上并不知道是否有人正在查看您的页面,最小化浏览器,将标签切换到自上次加载页面以来的3个不同的网页等。

编辑:我已更新示例以包含当前的API使用情况。

编辑2:更新托管项目的域

https://github.com/jasonzissman/TimeMe.js/

其用法示例:

包含在您的信息页中:

<!-- Download library from https://github.com/jasonzissman/TimeMe.js/ -->
<script src="timeme.js"></script>
<script type="text/javascript">
TimeMe.initialize({
    currentPageName: "home-page", // page name
    idleTimeoutInSeconds: 15 // time before user considered idle
});
</script>

如果您想自己向后端报告时间:

xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);

TimeMe.js还支持通过websockets发送计时数据,因此您不必尝试将完整的http请求强制转换为document.onbeforeunload事件。

答案 1 :(得分:31)

如果您使用Google Analytics,他们会提供此统计信息,但我不确定他们是如何获得的。

如果您想自己动手,则需要将一些AJAX请求发送到您的服务器进行记录。

jQuery有一个.unload(...)方法,您可以使用:

$(document).ready(function() {
  var start = new Date();

  $(window).unload(function() {
      var end = new Date();
      $.ajax({ 
        url: "log.php",
        data: {'timeSpent': end - start},
        async: false
      })
   });
});

在此处查看更多内容:http://api.jquery.com/unload/

这里唯一需要注意的是它使用了javascript的beforeunload事件,它并不总是有足够的时间来发出像这样的AJAX请求,所以合理地你会丢失很多数据。

另一种方法是使用某种类型的“STILL HERE”消息定期轮询服务器,该消息可以更一致地处理,但显然更昂贵。

答案 2 :(得分:8)

我想说最好的办法是跟踪服务器上每个会话ID的请求时间。用户在最后一页上花费的时间是当前请求的时间与先前请求的时间之间的差异。

这不会捕获用户访问的最后一页(即,当没有其他请求时),但我仍然采用这种方法,因为否则你必须提交请求onunload,这将非常容易出错。

答案 3 :(得分:6)

我认为最好的方法是将时间存储在cookie中的onload和unload事件处理程序中,例如然后在服务器端脚本中分析它们

答案 4 :(得分:5)

除了Jason的回答之外,如果您不想使用库,这里有一小段代码可以解决问题,它会考虑用户切换标签或关注另一个窗口。

let startDate = new Date();
let elapsedTime = 0;

const focus = function() {
    startDate = new Date();
};

const blur = function() {
    const endDate = new Date();
    const spentTime = endDate.getTime() - startDate.getTime();
    elapsedTime += spentTime;
};

const beforeunload = function() {
    const endDate = new Date();
    const spentTime = endDate.getTime() - startDate.getTime();
    elapsedTime += spentTime;

    // elapsedTime contains the time spent on page in milliseconds
};

window.addEventListener('focus', focus);
window.addEventListener('blur', blur);
window.addEventListener('beforeunload', beforeunload);

答案 5 :(得分:1)

根据正确答案,我认为这不是最佳解决方案。因为根据jQuery文档:

  

unload事件的确切处理因版本而异   浏览器版本。例如,某些版本的Firefox触发了   跟踪链接时的事件,但窗口关闭时不响应。在   在实际使用中,应该在所有支持的浏览器上测试行为   并与类似的前载事件形成​​对比。

另一件事是你不应该在文件加载后使用它,因为减去时间的结果可能是假的。

因此,更好的解决方案是将其添加到onbeforeunload部分末尾的<head>事件中,如下所示:

<script>
var startTime = (new Date()).getTime();

window.onbeforeunload = function (event) {
    var timeSpent = (new Date()).getTime() - startTime,
        xmlhttp= new XMLHttpRequest();
    xmlhttp.open("POST", "your_url");
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
    xmlhttp.send(timeSpent);
};
</script>

当然,如果您想使用空闲检测器计算时间,可以使用:

https://github.com/serkanyersen/ifvisible.js/

TimeMe 是我上面粘贴的包的包装。

答案 6 :(得分:0)

<body onLoad="myFunction()">
<script src="jquery.min.js"></script>
<script>
var arr = [];
window.onbeforeunload = function(){
var d = new Date();
var n = d.getTime();
arr.push(n);
var diff= n-arr[0];
var sec = diff/1000;
var r = Math.round(sec);
return "Time spent on page: "+r+" seconds";
};
function myFunction() {
var d = new Date();
var n = d.getTime();
arr.push(n);
}
</script>

答案 7 :(得分:0)

??????????????.???()

运行内联代码以获取用户到达页面的时间,从而阻止了页面的加载。而是使用performance.now()来显示自用户首次导航到页面以来已经经过了几毫秒。但是,Date.now测量的时钟时间可能会由于时间重新同步和leap秒等因素而与导航时间相差一秒或更长时间。 IE10 +和所有常绿浏览器(常绿=为了娱乐而不是牟利)都支持performance.now()。自Microsoft discontinued Windows XP in 2014起,至今仍存在的Internet Explorer最早的版本是Internet Explorer 11(最新版本)。

(function(){"use strict";

var secondsSpentElement = document.getElementById("seconds-spent");
var millisecondsSpentElement = document.getElementById("milliseconds-spent");

requestAnimationFrame(function updateTimeSpent(){
    var timeNow = performance.now();
    
    secondsSpentElement.value = round(timeNow/1000);
    millisecondsSpentElement.value = round(timeNow);
    
    requestAnimationFrame(updateTimeSpent);
});
var performance = window.performance, round = Math.round;
})();
Seconds spent on page:&nbsp; <input id="seconds-spent" size="6" readonly="" /><br />
Milliseconds spent here: <input id="milliseconds-spent" size="6" readonly="" />

答案 8 :(得分:0)

我发现使用 beforeunload 事件不可靠,实际上经常失败。通常在发送请求之前页面已被破坏,并且您会收到“网络故障”错误。

正如其他人所说,没有确定的方法可以判断用户在页面上停留了多长时间。不过,您可以发送一些线索。

点击和滚动是某人正在积极查看页面的相当公平的指标。我建议监听点击和滚动事件,并在每次触发时发送一个请求,尽管频率不超过每 30 或 60 秒一次。

可以在计算中使用一点智能,例如,如果每 30 秒左右触发一次事件,持续 5 分钟,然后 30 分钟没有事件,然后触发更多事件,很有可能,用户正在获取在 30 分钟内喝咖啡。

let sessionid;

function utilize(action) {
  // This just gets the data on the server, all the calculation is done server-side.

  let href = window.location.href;
  let timestamp = Date.now();
  sessionid = sessionid || timestamp;

  let formData = new FormData();
  formData.append('sessionid', sessionid);
  formData.append('timestamp', timestamp);
  formData.append('href', href);
  formData.append('action', action || "");

  let url = "/php/track.php";

  let response = fetch(url, {
    method: "POST",
    body: formData
  });
}

let inhibitCall = false;

function onEvent() {
  // Don't allow an update any more often than every 30 seconds.

  if (!inhibitCall) {
    inhibitCall = true;
    utilize('update');
    setTimeout(() => {
      inhibitCall = false;
    }, 30000);
  }
}

window.addEventListener("scroll", onEvent);
window.addEventListener("click", onEvent);

utilize("open");