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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4667068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:32:35  来源:igfitidea点击:

How to measure a time spent on a page?

javascriptjquery

提问by Richard Knop

I would like to measure a time (in seconds in integers or minutes in floats) a user spends on a page. I know there is an unload event which I can trigger when they leave the page. But how to get a time they have already spent there?

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

采纳答案by Kevin Dolan

If you use Google Analytics, they provide this statistic, though I am unsure exactly how they get it.

如果你使用谷歌分析,他们会提供这个统计数据,但我不确定他们是如何得到它的。

If you want to roll your own, you'll need to have some AJAX request that gets sent to your server for logging.

如果你想推出自己的,你需要有一些 AJAX 请求被发送到你的服务器进行日志记录。

jQuery has a .unload(...) method you can use like:

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
      })
   });
});

See more here: http://api.jquery.com/unload/

在此处查看更多信息:http: //api.jquery.com/unload/

The only caveat here is that it uses javascript's beforeunload event, which doesn't always fire with enough time to make an AJAX request like this, so reasonably you will lose alot of data.

这里唯一的警告是它使用了 javascript 的 beforeunload 事件,它并不总是有足够的时间来发出这样的 AJAX 请求,所以合理地你会丢失大量数据。

Another method would be to periodically poll the server with some type of "STILL HERE" message that can be processed more consistently, but obviously way more costly.

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

回答by jason.zissman

The accepted answer is good, but (as an alternative) I've put some work into a small JavaScript library that times how long a user is on a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignore times that a user switches to different tabs, goes idle, minimizes the browser, etc. The Google Analytics method suggested in the accepted answer has the shortcoming (as I understand it) that it only checks when a new request is handled by your domain. It compares the previous request time against the new request time, and calls that the 'time spent on your web page'. It doesn't actually know if someone is viewing your page, has minimized the browser, has switched tabs to 3 different web pages since last loading your page, etc.

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

Edit: I have updated the example to include the current API usage.

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

Edit 2: Updating domain where project is hosted

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

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

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

An example of its usage:

其用法示例:

Include in your page:

包括在您的页面中:

<!-- 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>

If you want to report the times yourself to your backend:

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

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 also supports sending timing data via websockets, so you don't have to try to force a full http request into the document.onbeforeunloadevent.

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

回答by dxh

I'd say your best bet is to keep track of the timing of requests per session ID at your server. The time the user spent on the last page is the difference between the time of the current request, and the time of the prior request.

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

This won't catch the very last page the user visits (i.e. when there isn't going to be another request), but I'd still go with this approach, as you'd otherwise have to submit a request at onunload, which would be extremely error prone.

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

回答by heximal

i think the best way is to store time in onload and unload event handlers in cookies e.g. and then analyze them in server-side scripts

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

回答by martpie

In addition to Jason's answer, here's a small piece of code that should do the trick if you prefer to not use a library, it considers when the user switch tabs or focus another window.

除了 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);

回答by Hyman Giffin

.()

.()

Running inline code to get the time that the user got to the page blocks the loading of the page. Instead, use performance.now()which shows how many milliseconds have elapsed since the user first navigated to the page. Date.now, however, measures clock-time which can differ from navigation-time by a second or more due to factors such as Time resynchonization and leap seconds. performance.now()is supported in IE10+ and all evergreen browsers (evergreen=made for fun, not for profit). The earliest version of internet explorer still around today is Internet Explorer 11 (the last version) since Microsoft discontinued Windows XP in 2014.

运行内联代码以获取用户到达页面的时间会阻止页面加载。相反,使用performance.now()which 显示自用户第一次导航到页面以来已经过去了多少毫秒。Date.now但是,由于时间重新同步和闰秒等因素,测量时钟时间可能与导航时间相差一秒或更多。performance.now()支持 IE10+ 和所有常青浏览器(常青=为了好玩而不是为了盈利)。自微软于 2014 年停止使用 Windows XP以来,今天仍然存在的最早版本的 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="" />

回答by Filip Koblański

According to the right answer I think thats is not the best solution. Because according to the jQuery docs:

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

The exact handling of the unload event has varied from version to version of browsers. For example, some versions of Firefox trigger the event when a link is followed, but not when the window is closed. In practical usage, behavior should be tested on all supported browsers and contrasted with the similar beforeunload event.

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

Another thing is that you shouldn't use it after documents load because the result of substraction of time can be fake.

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

So the better solution is to add it to the onbeforeunloadevent in the end of the <head>section like this:

所以更好的解决方案是将它添加到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>

Of course if you want to count the time using Idle detector you can use:

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

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

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

TimeMeis a wrapper for the package that I paste above.

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

回答by babiro

<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>